Authorization Code

Web Applications (Server)Single Page ApplicationsMobile Applications
DiscouragedNot SupportedNot Supported

The Authorization Code Flow is the most common OAuth 2.0 flow. It can be used by web applications that run on a server and therefore can securely store their client secret. Neverthless, we recommend to use the Authorization Code Flow with PKCE flow instead. It is more secure and can be used by all types of applications. The next version of the OAuth 2.0 specification will deprecate the Authorization Code Flow. We only support it for backwards compatibility.

Migrating to Authorization Code with PKCE

If you are currently using the Authorization Code Flow, you should migrate to the Authorization Code Flow with PKCE flow. It is based on the Authorization Code Flow and therefore very similar. The flow is basically the same and just adds an additional security layer to prevent authorization code interception attacks. The flow is by now widely used and should be avaliable in all OAuth 2.0 libraries.

We will deprecate the Authorization Code Flow in the future and remove it at some point. Even though we will announce the deprecation in advance and will give you enough time to migrate, it's best to start with the more secure flow right away.

This flow is outdated! You should not implement this flow anymore. Even though we will support it for a while, we will deprecate it in the future. Use the Authorization Code Flow with PKCE flow instead.

Overview

The Authorization Code flow consists of five major steps:

  1. The user clicks on your Tile in the Eduplaces platform, opening your Login URL in a new tab or the user clicks on a "Login with Eduplaces" button in your application.
  2. The user is redirected to our authorization server to authenticate and authorize your application.
  3. The user is redirected back to your application with an authorization code.
  4. Your application exchanges the authorization code for an ID and access token.
  5. Your application uses the ID token to identify the user and the access token to make API requests on behalf of the user.

The following diagram shows the flow in detail:

Authorization Code Flow

Step 1: Start an Authentication

Authentication is always started by an user interaction. This could be:

  • The user clicking on your Tile in the Eduplaces platform, opening your Login URL in a new tab.
  • The user clicking on a "Login with Eduplaces" button on your applications login page.

Step 2: Request User Authorization

Your application redirects the user to our authorization server to authenticate and authorize your application. This is done by sending an authentication request to our authorization endpoint. The GET request can include the following query parameters:

Query ParameterValue
response_typerequired Always set to code to indicate the flow to be used.
client_idrequired The client ID of your application.
redirect_urirequired The URL we will redirect the user back to after they authorized your application. This must exactly match one of your pre-registered allowed redirect URIs for your client.
scoperequired A space-separated list of scopes your application is requesting access to. You have to include openid to receive an ID token.
statestrongly recommended A random string generated by your application. This will be included in the response from our authorization server and can be used to verify the response. We provide some tips below.
noncestrongly recommended A random string generated by your application. This will be included in the ID token and can be used to verify the token.
login_hintoptional or required A string telling our authorization server to make sure a specific user is logged in. This is only required if the flow was started via your Login URL and we included a login_hint parameter.
promptoptional A space-separated list of strings that define whether the user should be prompted for reauthentication and consent. Values are none, login, consent. See prompt Parameter for more information.
id_token_hintoptional A previously issued ID token. If the user identified by the ID Token is logged in or is logged in by the request, then the Authorization Server returns a positive response; otherwise, it returns an error. This could be used in combination with prompt=none to check if the user is still logged in.
max_ageoptional Maximum Authentication Age. Specifies the allowable elapsed time in seconds since the last time the End-User was actively authenticated by Eduplaces. If the elapsed time is greater than this value, we will reauthenticate the user. Usage is discouraged!
HTTP/1.1 302 Found
Location: https://auth.eduplaces.io/oauth2/auth
          ?response_type=code
          &client_id=YOUR_CLIENT_ID
          &redirect_uri=https://your.awesome-education.app/sso/callback
          &scope=openid school profile
          &state=YOUR_STATE
          &nonce=YOUR_NONCE
Heads up: There are plenty of open source libraries available that can help you with the authentication request. We recommend using one of them instead of building your own.

The user will be redirected to our authorization server where they can log in and authorize your application. If the user is already logged in, they will be asked to authorize your application right away. We remember the user's decision and will not ask them again for the same application.

Step 3: Redirect back to your Application

After the user authorized your application, they will be redirected back to your application with an authorization code. The authorization code is a short-lived, one-time code that can be exchanged for an ID and access token.

To which URI we redirect the user depends on the redirect_uri parameter you included in the authentication request. Just keep in mind that the redirect URI must exactly match one of your pre-registered allowed redirect URIs for your client. We will also redirect the user to the redirect_uri if they denied your application access to their data or if they canceled the authentication process.

Successful Response

If the user authorized your application, we will redirect them back to your application with an authorization code and the state you included in the authentication request. The GET request will include the following query parameters:

Query ParameterValue
codeThe authorization code your application can use to obtain an ID and access token.
stateThe state you included in the authentication request.
GET https://your.awesome-education.app/sso/callback
    ?code=ory_ac_MLN1fCSPt1v85onDiZM5FbBhXq2SVFPBQITrGYk4dr8.766I7lY1jKYKadkBikQjcugyt5ki8lDT3u8-JVei-Sc
    &state=YOUR_STATE

Error Response

If the user denied your application access to their data or if they canceled the authentication process, we will redirect them back to your application with an error. The GET request will include the following query parameters:

Query ParameterValue
errorThe error code.
error_descriptionA human-readable text providing additional information.
stateThe state you included in the authentication request.
GET https://your.awesome-education.app/sso/callback
    ?error=access_denied
    &error_description=The+resource+owner+or+authorization+server+denied+the+request.
    &state=YOUR_STATE

Refer to the OpenID Connect specification for a list of error codes. The error_description is optional and might not be included in the response. We will try to include it if possible, but you should not rely on its presence.

Important: The state parameter is only included in the response if you included it in the authentication request. You should always verify that the state parameter in the response matches the state parameter you included in the authentication request.

Step 4: Exchange Authorization Code for Tokens

The user is now back on your application and you can exchange the authorization code for an ID and access token. To do so, you have to send a POST request to our token endpoint. As this flow is only available for confidential clients, you have to authenticate yourself by including your client ID and secret in the Authorization header.

Never make your client secret public! Never include the client secret in a request from a public client like a single page application or a mobile application.

To exchange the authorization code for an ID and access token, you have to make a POST request to our token endpoint. The POST request must include the following parameters in the body:

Request Body ParameterValue
grant_typerequired Always set to authorization_code to indicate you are exchanging an authorization code for an ID and access token.
redirect_urirequired The Redirect URI used while requesting the authorization code.

In addition to the request body parameters, you have to set the following headers:

HeaderValue
Content-Typerequired Set to application/x-www-form-urlencoded. This will most likely be set automatically by your HTTP client.
Authorizationrequired Set to Basic <base64(client_id:client_secret)>. Never include the client secret in a request from a public client like a single page application or a mobile application.
POST /oauth2/token HTTP/1.1
Host: auth.eduplaces.io
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=ory_ac_MLN1fCSPt1v85onDiZM5FbBhXq2SVFPBQITrGYk4dr8.766I7lY1jKYKadkBikQjcugyt5ki8lDT3u8-JVei-Sc
&redirect_uri=https://your.awesome-education.app/sso/callback
Heads up: You don't have to implement all of this yourself. This is standard OAuth 2.0 stuff and there are plenty of open source libraries available that can help you with the token request. We recommend using one of them instead of building your own.
Successful Response

If the request was successful, we will respond with a 200 OK status code and a JSON body containing the following parameters:

KeyValue
access_tokenThe access token your application can use to make API requests on behalf of the user.
token_typeThe type of the access token. Always set to bearer. Note: It should be Bearer but unfortunately, our OAuth 2.0 server returns it in lowercase. Make sure to be able to handle both as this might change.
expires_inThe remaining lifetime of the access token in seconds.
scopeThe scopes the user authorized your application to access.
id_tokenThe ID token your application can use to identify the user. Requires the openid scope.
refresh_tokenThe refresh token your application can use to obtain a new access token when the current one expired and the user is not present to re-authorize your application. Requires the offline_access scope. Learn more about Refresh Tokens.
HTTP/1.1 200
Content-Type: application/json
{
  "access_token": "ory_at_FYfL9jJTZO15HI6EQCO-0uZg8W_KMTJHunpmXTLp8lg.uGGOCQEGOlunY9mdsWrZA3uGT03JYWdTTj8iar5MIvs",
  "token_type": "bearer"
  "expires_in": 3599,
  "scope": "openid offline_access",
  "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ijg4MzIwZjlmLTBhZjQtNDFjMC1iMzAwLTczMGFmZmRjYjVhMCIsInR5cCI6IkpXVCJ9.eyJhdF9oYXNoIjoiSXdDQmFTc0tEZTI3R1JQQS12NG1JUSIsImF1ZCI6WyJkYzYxZjk5ZC1hZGZlLTQ1OGEtODZiZi0zYTMxNmYyYTc4OWMiXSwiYXV0aF90aW1lIjoxNjkzMzAyNzAwLCJleHAiOjE2OTMzMDYzMTQsImlhdCI6MTY5MzMwMjcxNCwiaXNzIjoiaHR0cHM6Ly9zaWxseS1lbGlvbi13ZWN4dHhtY2c1LnByb2plY3RzLm9yeWFwaXMuY29tIiwianRpIjoiMWMyZDUzMmQtMWUzNi00ZmFiLTkwMjgtMjc1MDcwM2FiMTczIiwicmF0IjoxNjkzMzAyNjkzLCJzaWQiOiIzM2RiOWU3Ny1iNGRiLTQ2M2YtOTc4My1kZmY3NmU5NDQxNDciLCJzdWIiOiI3NGQ3YjYyNS01YzA4LTRjYmItOWQwZC1lZWQxZTgzNjQ2YzMifQ.EPWFwVioQZYxmaZVy_3drs2-3jr2DIszkrI9TZpz6dJluDPQ6F6M2Kq7q-zKthnHM7rWvb-bfBJh6Olo1UF6TG0F93WXQIdI7HgIhtQH5a9Cfwbv-h8GQieVc2cQmxzqyiqIxa4e0Z3VoLvsqCE76JVfdo0tmI1SfnauYx3BSxlu6LeVzYWWclQU9fJg1pfurvw6hzVdtJTjdyUvh45bNMAb_QWFDMhkF36yMX7CqzVd8eHX5jnMuk2e1WDLKS6qZxJ3oGux_VDqKg9Qu0x8rb1e4WPAJJ35n2AcqmsO0ex14yxUfhCZDRM31MMC11MfIH1wiTrZKTF9EqZ0yys_vZoQ8DBoHvnDA7cjYZ-0FXO1cirDflzo0jMxihwFaES-_E1pAr4vkiInIigSc4YmTMfOyTttlT-U31zlOh5tiaLhzLO9ImmyLenj9CGCi_GYPqoLf0JTbeSKA9J7DkrO-ed_xMYn-fHt1oqukJmEVg7KJz3Ey5G4h_mL8wMR2Vj-wopFC01RIYpo3a-KjEPdFUktyNB678-iY-n0JuEdDLJ743RfWsR4zQOKpfy3XMK3jIfcE_sAg5Yz3rgUWtVdZ_NSy1rvOCzbJ3-PoxzGNS1qbp6Ma0aK-FU_ZHyUnLRoRa5O6q1vwLe-DX5nfsfIX9S2FapS6nTC_hPITyq9YRI",
  "refresh_token": "ory_rt_XfPjrVDSXtVXK-WA9rbjAp5g7ZkAG-hXR76nN38VIAM.disRRBbHn71r2JfpLKuiq3F5EyJPKg7dmWQZdsFm-rw",
}

Error Response

If the request was not successful, we will respond with an error. The authorization server will respond with a 400 Bad Request status code and a JSON body containing the following parameters:

KeyValue
errorThe error code.
error_descriptionA human-readable text providing additional information.
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
  "error": "invalid_request",
  "error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed."
}

Refer to the OAuth 2.0 specification for a list of error codes. The error_description is optional and might not be included in the response. We will try to include it if possible, but you should not rely on its presence.

Step 5: Use the ID Token to Identify the User

To Authenticate the user, you have to verify the ID token. The ID token is a JSON Web Token (JWT) that contains information about the user and is signed by Eduplaces. Part of the information is the user's unique ID, which you can use to identify the user in your application. The ID token can also contain information about the user's school and role. Head over to our Scopes section for more information on the available additional claims.

Validating the ID token is a two-step process:

  1. Verify the signature of the ID token to ensure it was signed by Eduplaces.
  2. Verify the claims in the ID token to ensure the token is valid.

How to verify the signature is out of scope for this documentation. We recommend using one of the many open source libraries available that can help you with the ID token validation. In our Authenticate Users Guide, we provide a full example you can use as a reference.

On our Endpoints page, you can find the URLs containing the public keys you can use to verify the signature of the ID token. Common libraries will be able to automatically fetch the public keys automatically by using the OpenID Connect Discovery endpoint we provide.

Heads up: Again, do not go down the path of implementing this yourself. There are plenty of open source libraries available that can help you with the ID token validation. It's probably already included in the library you are using for the authentication request.

The ID token contains a JSON object with at least the following claims:

ClaimDescription
issThe issuer identifier for the issuer of the response. Always set to https://auth.eduplaces.io.
audArray containing the client ID of your application.
subThe unique identifier for the user.
nonceThe nonce you included in the authentication request.
jtiA unique identifier for the token.
sidThe Eduplaces session ID.
at_hashThe access token hash.
auth_timeThe time the user authenticated.
ratThe time the ID token was requested.
iatThe time the ID token was issued.
expThe expiration time of the ID token.

If you requested additional scopes, the ID token can contain additional claims. Head over to our Scopes section for more information on the available additional claims.

{
  "iss": "https://auth.eduplaces.io",
  "aud": [
    "YOUR_CLIENT_ID"
  ],
  "sub": "f80763f1-96da-4071-b29d-1f15d83ca8b6",
  "nonce": "YOUR_NONCE",
  "jti": "30e58376-ed53-4c5b-91c1-9fd5517e7f55",
  "sid": "7ddc71e6-e932-43e5-9d86-2ada68a490af",
  "at_hash": "cw8qL0ENYRYrslktjHXEtw",
  "auth_time": 1692706900,
  "rat": 1692706896,
  "iat": 1692706914,
  "exp": 1692710514
}

The most important claim when authenticating a user is the sub claim. It contains the unique identifier for the user. You can use this identifier to identify the user in your application and log them in automatically. Just like you would with a username and password.

If you receive an ID token with a sub claim you don't recognize, you should create a new user account on-the-fly in your database and associate it with the user's Eduplaces ID. The next time the user logs in to your application with Eduplaces, you can use the ID token to identify the user and log them in automatically.

Congratulations 🥳 You successfully authenticated a user with Eduplaces via Single Sign-On. This was all very abstract, so we will guide you through the process with actual code examples in our Authenticate Users Guide. It's by far not as hard as you might think.

Additional Information

state Parameter

The state parameter is a random string generated by your application. It is included in the response from our authorization server and can be used to verify the response. You should always verify that the state parameter in the response matches the state parameter you included in the authentication request. It is strongly recommended to include the state parameter in the authentication request as it can prevent CSRF attacks.

Some documentation you might find on the internet recommends to use the state parameter to store the user's session. This is not recommended as it can lead to session fixation attacks. Instead, you should use a session cookie to store the user's session and store the state parameter in the session.

This is how we recommend to use the state parameter:

  • Create a random string when the user starts the authentication flow.
  • Store the random string in a protected cookie (secure and httpOnly) for server-side web applications, in Local Storage for single page applications, or in a protected key-value store for mobile applications.
  • Include the random string as state in the authentication request.
  • Verify that the state parameter in the response matches the random string you stored in the cookie, Local Storage, or key-value store.
  • Delete the random string from the cookie, Local Storage, or key-value store.

As the state is stored in a cookie, Local Storage, or key-value store on the user's device, it is not possible to resume a flow in another browser or device by knowing the state. This is a good thing as it prevents session fixation attacks.

prompt Parameter

The prompt parameter is a space-separated list of strings that define whether the user should be prompted for reauthentication and consent. There is no need to include the prompt parameter if you only want to authenticate the user. Only include it if you have a specific use case for it.

The following values are supported:

  • none: The user should not be prompted for reauthentication or consent. If the user is not logged in or if they are logged in but haven't authorized your application yet, we will respond with an error.
  • login: The user should be prompted for reauthentication even if they are currently logged in.
  • consent: The user should be prompted for consent.

The prompt parameter is useful in combination with the id_token_hint parameter if you want to make sure the user is still logged in on Eduplaces. This could be the case if the user is logged in to your application but hasn't used it for a while. In this case, you could include the prompt=none parameter in the authentication request and the id_token_hint parameter with the ID token you received the last time the user logged in even if it is expired.

This concept is also known as Silent Authentication as the user is not prompted for reauthentication or consent.