Als je applicatie aangemeld is bij Congressus en je je client_id
en client_secret
hebt ontvangen kan je beginnen met leden laten inloggen via Congressus.
Stap 1: Stuur een onbekende gebruiker door naar congressus
Genereer een willekeurige
state
en sla deze op in het cookie van de gebruiker voor latere verificatieMaak een lijst van scopes waar je toegang tot wilt, gescheiden door spaties. Bijvoorbeeld:
openid profile email
Stuur de gebruiker door naar de verenigingswebsite met het volgende url:
https:// your_congressus_domain /oauth/authorize?response_type=code id_token&client_id=client_id&scope=scopes&state=state
Voorbeeld:
Je verenigingsdomein is www.vereniging.nl, jeclient_id
is 123456, je scopes zijnopenid profile email
en je hebt de state1a2b3c4d5e6f
gegenereerd. Je url word dan:
https://www.vereniging.nl/oauth/authorize?response_type=code id_token&client_id=123456&scope=openid profile email&state=1a2b3c4d5e6f
Stap 2: De gebruiker komt terug naar jouw applicatie
Congressus checkt of de gebruiker is ingelogd op de verenigingswebsite. Zo niet, dient de gebruiker eerst in te loggen. Daarna word gevraagd of jouw applicatie toegang mag hebben tot de gevraagde gegevens van de gebruiker mits dat nodig is volgens de instellingen van Silent en No Grants. De gebruiker wordt daarna teruggestuurd naar het url dat je bij het aanmelden van de applicatie bij Congressus hebt opgegeven.
Er is een fout opgetreden
Het kan zijn dat er een fout is opgetreden bij het aanmelden. Achter het doorstuur url van jou applicatie wordt dan ?error=error_msg
geplakt. error_msg
kan een aantal waarden hebben:
unauthorized_client
Je applicatie is nog niet geauthoriseerd bij Congressusunsupported_response_type
Je probeert eenresponse_type
aan te vragen die niet toegestaan is. Toegestaan is:id_token
,code
of een combinatie van beide (gescheiden door een spatie)invalid_scope
Je probeert een scope aan te vragen die niet bestaat of die je applicatie niet mag aanvragen. Let op! Scopes dienen te worden gescheiden door middel van een spatie. Een komma werkt bijvoorbeeld niet en levert deze error op.access_denied
Het lid heeft je applicatie geen toestemming gegeven. Vaak is dit omdat het lid je applicatie niet kent of omdat deze de gevraagde toestemmingen als te breed ziet.
Het lid is successvol geauthenticeerd en heeft jouw applicatie toestemming gegeven
Het lid word teruggestuurd naar het url dat je hebt opgegeven bij het aanmelden van jouw applicatie bij Congressus. Achter het url plakken we het volgende ?code=code&state=state
Bijvoorbeeld:
Je hebt de state 1a2b3c4d5e6f
gegenereerd en je redirect url is https://eetmee.vereniging.nl/oauth/return
.
Wij sturen het lid dan door naar:
https://eetmee.vereniging.nl/oauth/return?code=4WOSENHMG4MYCMB5BGGCJXHILVATNVOPXBRODIN3WOOI44XRXLIA&state=1a2b3c4d5e6f
Let op! Het is niet verplicht maar wel veiliger om de "state" te verifiëren met de state die je hebt aangemaakt in het begin, zo weet je dat het dezelfde persoon is die terugkomt op jouw applicatie.
Stap 3: Ruil de code in voor een token
De code die je hebt gekregen in het url hiervoor is maar 60 seconden geldig en alleen jouw applicatie kan hem inruilen voor een access_token
(en evt. id_token
mits je als response_type ook id_token
hebt aangevraagd).
Je kan de code inruilen door een POST
request naar het volgende endpoint te doen: https:// your_congressus_domain /oauth/token
je verzoek moet aan de volgende eisen voldoen:
Gebruik HTTP Basic authenticatie met als gebruikersnaam je
client_id
en als wachtwoord jeclient_secret
Gebruik als
Content-Type
:application/x-www-form-urlencoded
Je request body moet het volgende bevatten:
grant_type=authorization_code&code=code
(gebruik hiervoor de code uit stap 2)
Let op! Dit verzoek dient door jouw server gemaakt te worden. Laat dit nooit door de browser van het lid doen, omdat je dan je client_secret
laat lekken. Congressus kan ten alle tijden jouw applicatie blokkeren als wij het vermoeden krijgen dat je client_secret niet meer geheim is.
Er is een fout opgetreden
Je krijgt een response terug met als Content-Type
: application/json
. In dit geval zal de response zijn:
{"error": "error_message"}
error_message
kan de volgende waardes hebben:
invalid_client
Je hebt geen HTTP Basis authenticatie gebruikt óf jeclient_id:client_secret
combinatie is niet geldig.unsupported_grant_type
Je waarde voorgrant_type
is ongeldig (magrefresh_token
ofauthorization_code
zijn)invalid_request
Je hebt geencode
parameter meegegeven in de body.invalid_grant
Je code is verlopen, incorrect, ingetrokken, eerder gebruikt, je applicatie is vergrendeld of het lid is niet meer actief.
Je code is geldig en is omgewisseld
Je krijgt de volgende response terug:
{
"access_token":"The Access Token",
"refresh_token":"The optional Refresh Token",
"token_type":"bearer",
"expires_at": "2019-02-19 13:46:13.820105"
"user_id":"The Congressus User Id (This is not the username)",
"name":"The name of the Congressus User",
"id_token":"The optional JWT Token of the user if the scope openid is
present. HS256 signed with the client_secret."
}
De velden betekenen het volgende:
access_token
Dit token kan je zometeen gebruiken om toegang te krijgen tot de aangevraagde informatie van het lid.refresh_token
(optioneel)
Met het refresh token kan je een nieuwaccess_token
aanvragen als deze verlopen is. Word alleen meegeleverd als jouw applicatie toestemming heeft voorrefresh_tokens
token_type
Dit is altijdbearer
expires_at
Wanneer hetaccess_token
verloopt. Let op! Dit is in de UTC/GMT+0 tijdzone. Dit is niet de Nederlandse tijdzone!user_id
Het Gebruiker ID binnen Congressus. Dit is niet het Lid ID maar kan gebruikt worden in de API.name
De naam van de gebruikerid_token
(optioneel)
Als je deopenid
scope hebt gekregen, krijg je hier een JWT token terug. Deze lijkt op een willekeurige reeks, maar kan je decoderen met een JWT library. De token is ondertekend met het algoritmeHS256
met als sleutel jeclient_secret
. De inhoud van het token is als volgt:
{
"iss": "urn:congressus:nl",
"sub": "The Congressus User Id (This is not the username)",
"name": "The Members full name",
"status_id": "The id of the current status.",
"gender": "The gender of the member",
"aud": "Your client_id",
"nonce": "The nonce you provided",
"exp": "When your access_token expires",
"iat": "When this token was issued",
"auth_time": "When the user was authenticated (same as iat)",
"acr": "urn:c2id:acr:silver",
"amr": ["pwd"]
}
iss
Dit token is afgegeven door Congressus (urn:congressus:nl
)
sub
Het subject van dit token, het Gebruikers ID binnen Congressus
name
Volledige naam van het lid
status_id
ID van de huidige lidstatus van het lid
gender
Geslacht van het lid
nonce
De waarde vanstate
exp
Wanneer jeaccess_token
verloopt
iat
Wanneer dit token afgegeven is
auth_time
Zelfde alsiat
, wanneer de authenticatie plaatsvond
acr
Hoe zeker we zijn van de authenticatie (altijdurn:c2id:acr:silver
)
amr
Hoe het lid is ingelogd (altijdpwd
)
Stap 4: Haal extra informatie van het lid op
Met het geldige access_token
kun je extra informatie van het lid opvragen op het user_info url: https:// your_congressus_domain /oauth/userinfo
Hiervoor dien je de volgende header mee te geven:
Authorization: Bearer access_token
Op basis van de scopes die je hebt aangevraagd krijg je de volgende informatie als JSON response (let op, dit endpoint is alleen beschikbaar met de openid
scope):
{
"user_id":"The Congressus User Id (This is not the username)",
"is_active":"If the user is an active user.",
// for scope ’profile’
"username":"The username of the Member (first column in members list in manager)",
"name":"Full name of the Member",
"picture":"The url to the picture of the Member if Member has one set",
"gender":"The gender of the Member (m or f)",
"birthday":"ISO Formatted date of birth",
"member_status":"Name of current status of the Member",
"member_status_id":"The status id of the current status of the Member.",
"member_status_since":"ISO Formatted date when Member entered current status.",
"member_since":"ISO Formatted date of when the Member joined the Association",
// for scope ’email’
"email":"The Members email address",
// for scope ’address’
"address": {
"formatted":"The formatted full address",
"street_address":"The street and streetnumber",
"locality":"The city",
"region":"The province",
"postal_code":"The postal code",
"country":"The country"
},
// for scope ’phone’
"phone":"The Members mobile phone number as MSISDN.",
// for scope ’bank’
"IBAN":"The Members IBAN",
"BIC":"The BIC for the IBAN",
// for scope ’profile_custom’ (This scope is rarely granted)
"custom":{
"field_reference_1": "value_1", // Type depends on field.
"field_reference_2": "value_2", // etc.
},
// for scope ’groups’
"groups":{
"group_slug_1": {"active": true/false},
"group_slug_2": {"active": true/false}, // etc.
},
}