Skip to main content

OAuth Integration with Subrite OIDC

Subrite provides Web Application Flow to authorize users with standard OAuth that runs in the browser.

To enable OAuth login in your application, you need to register your application from Subrite Admin Portal. You will receive client ID, client secret, and redirect URI from Subrite Admin Portal for your application. Once you have the required params, you can follow the steps below to enable OAuth login.

Subrite OIDC follows PKCE standards. So, you need to add code_challenge_method and code_challenge when you make the very first request to authenticate. If you use any standard library to generate code, you also need to have code_verifier so you can later use it to get access tokens.


Required Params

  • Client ID (client_id)
  • Client Secret (client_secret)
  • Redirect URI (redirect_uri)

Flow Steps

  1. Users will be redirected to Subrite OIDC login page
  2. Users will be authenticated
  3. Users will be redirected to the registered redirect URI

Environment URLs

  • Stage URL: [Will be provided after prepared]
  • Production URL: [Will be provided after prepared]

1. Redirecting to Subrite Login Page

Endpoint

GET /api/oidc/auth

ParameterRequiredTypeDescription
response_typeYesstringGrant to execute. Only code is currently supported.
client_idYesstringYour Client ID.
redirect_uriYesstringA successful response from this endpoint results in a redirect to this URL. Must include all registered redirect URIs.
code_challenge_methodYesS256Required as we have PKCE enabled.
code_challengeYesstringBase64 encoded SHA256 hashed long character string.
scopeYesstringopenid, offline_access
stateNostringAn opaque value, used for security purposes. If this request parameter is set in the request, then it is returned to the application as part of the redirect_uri.

Note about redirect_uri

If a tenant assigns multiple redirect_uris to a single client ID in Subrite, every request must include a redirect_uri.
If multiple redirect_uris are registered in Subrite and a request lacks a redirect_uri, an exception will be thrown.

Example:

redirect_uri=http%3A%2F%2Flocalhost%3A3010%2Fcallback,http%3A%2F%2Flocalhost%3A3010%2Falt-callback

The request should look as follows:

http://{{subriteUrl}}/api/oidc/auth?client_id=-client-id&response_type=code&scope=openid+offline_access&redirect_uri=http%3A%2F%2Flocalhost%3A3010%2Fcallback&code_challenge=abc&code_challenge_method=S256&state=def

2. Authenticated User

Once the user completes the request in Step 1, they will be redirected to the Subrite OAuth login page and asked to authenticate.

Authentication Process:

  • The user enters their credentials and logs in.
  • After successful authentication, the user will be redirected to the registered redirect_uri.
  • The response will contain:
    • A temporary authorization code (code).
    • The state parameter (if provided in the initial request).

Important Notes:

  • The authorization code is valid for only 10 minutes.
  • This code must be exchanged for an access token in the next step.

3. Exchange Code for a Token

Once a user comes in redirect_uri, the user will receive code from the request URL.
The user will make a POST request to the token endpoint with the following parameters:

  • code
  • code_verifier
  • grant_type
  • client_id
  • client_secret

The user should have the code_verifier when the user generates code_challenge in Step 1.
If the user makes a POST request to the token endpoint, they will receive an access token and a refresh token.

Token Endpoint

POST /api/oidc/token

Headers

Content-Type: application/x-www-form-urlencoded
Accept: application/json

Required Parameters

ParameterRequiredTypeDescription
grant_typerequiredstringauthorization_code
client_idrequiredstringYour Client ID.
client_secretrequiredstringYour Client Secret.
coderequiredstringThe code you received as a response in code parameter in Step 2.
code_verifierrequiredstringCode that is stored in session when the user generated code_challenge in Step 1.

Response

{
"token_type": "<string>",
"expires_in": <integer>,
"access_token": "<string>",
"refresh_token": "<string>",
"id_token": "<string>",
"scope": "<string>"
}

Here is an example for making request to token endpoint

Token Request

Use Access Token to Make Requests to Subrite API

Once you have the access token, you can use it in the Authorization header as a Bearer token to access resources from the Subrite API.

Example Request:

curl --location 'https://stage.api.subrite.no/api/v1/members/profile/info-with-active-subscriptions' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE3MDQ4NTk4NjIsInN1YiI6NSwiaXNzIjoiaHR0cHM6Ly9taW5zaWRl'

API Base URLs:

Response Sample

subscriptions: Only returns active subscriptions.
If subscriptions.length === 0, the user does not have active subscriptions.

{
"id": "string", // Updated: memberId is now a string,Ex: "1", "c29a724f-36cf-4584-9d47-1cdde8733f75" etc
"fullName": "string",
"email": "string",
"userType": "system_admin",
"phone": "+4793155389",
"avatar": null,
"nickName": "",
"memberNumber": 1234, // memberNumber is a number
"address": {
"line1": null,
"city": null,
"postCode": null,
"postOffice": null,
"country": "NO",
"name": null,
"email": null
},
"subscriptions": [
{
"subscriptionId": 1,
"packageId": 2,
"packageName": "example package",
"status": "active",
"createdAt": "2024-01-08T13:49:59.350Z",
"activatedAt": "2024-01-08T13:49:59.350Z",
"expiresAt": "2024-01-08T13:49:59.350Z",
"subscriptionProducts": [
{
"id": 1,
"name": "example product"
}
],
"customPropertyValues": {
"muscNumber": 1234,
"localClub": "",
"mufcNumber": 1234568,
"mufcExpiration": "2023-12-27T18:00:00.000Z"
}
}
]
}

Get Refresh Token

To get a new access token using the refresh token, you can use the same token endpoint with grant_type set to "refresh_token".

Example Request:

Token Endpoint

POST /api/oidc/token

Headers

Content-Type: application/x-www-form-urlencoded
Accept: application/json

Required Parameters

ParameterRequiredTypeDescription
grant_typerequiredstringrefresh_token
client_idrequiredstringYour Client ID.
client_secretrequiredstringYour Client Secret.
refresh_tokenrequiredstringThe refresh token you received in step 3.

Logout

When you register in Subrite Admin Portal, you will also provide input for post_logout_redirect_uri.
When implementing logout in your application, you must ensure that the user is logged out from both Subrite and your application.

Logout Flow

  1. Log out from Subrite first

    • The browser must visit the Subrite logout endpoint.
    • The Subrite logout endpoint will then redirect back to your application's configured post_logout_redirect_uri.
  2. Log out from your application

Subrite Logout Endpoint

To log out from Subrite, you need to make a GET request to:

GET /api/oidc/session/end

You can also specify which client you are signing out from:

GET /api/oidc/session/end?client_id=your_client_id

Post Logout Redirection

After logging out from Subrite, the user will be redirected to the configured post_logout_redirect_uri.

PHP Sample Code for Integrating Subrite OIDC

[Note] We strongly recommend using a popular OpenID Connect library from your programming language of choice.
The example code shown below is written in vanilla PHP (without using any library), but you can achieve the same functionality using any OpenID Connect library.

Making a Request to Subrite OIDC with Client ID, Secret, and Code

 public function login(Request $request)
{

$codeVerifier = bin2hex(random_bytes(64));
$codeChallenge = rtrim(strtr(base64_encode(hash('sha256', $codeVerifier, true)), '+/', '-_'), '=');
$state = \bin2hex(\random_bytes(16));

session()->put('openid_connect_code_verifier', $codeVerifier);

$authorizeUrl = 'http://localhost:3000/api/oidc/auth' ;
$clientId = 'example-client-id';
$redirectUri = 'http://localhost:3010/callback';

$query = [
'client_id' => $clientId,
'response_type' => 'code',
'scope' => 'openid offline_access',
'redirect_uri' => $redirectUri,
'code_challenge' => $codeChallenge,
'code_challenge_method' => 'S256', // required as have PKCE support enabled
'state' => $state,
];

$url = $authorizeUrl . '?' . http_build_query($query);

return redirect()->away($url);
}

Making a Request for Access Token

After receiving the authorization code in the callback, you need to make a request to the token endpoint to exchange it for an access token.

PHP Example:

public function callback(Request $request) {
$tokenEndpoint = 'http://localhost:3000/api/oidc/token';
$code = $request->get('code');
$codeVerifier = session()->get('openid_connect_code_verifier');

$response = Http::asForm()->post($tokenEndpoint, [
'code' => $code,
'grant_type' => 'authorization_code',
'client_id' => 'example-client-id',
'client_secret' => 'example-client-secret',
'code_verifier' => $codeVerifier,
]);

session()->forget('openid_connect_code_verifier');

return $response->json();
}

Get Logged-In Member Info with Content Access

Description

Retrieve detailed information about the logged-in member, including their content access rights.

More details on this API can be found here: Get logged in member info with content access

Get Logged-In Member Info with Active Subscriptions API

Description

Retrieve detailed information about the logged-in member, including their active subscriptions.

More details on this API can be found here: Get logged-In member info with active subscriptions API

5. Checkout Search Params

1. reference

Indicates the source from which the user is navigating to the checkout page.
It helps track the origin of the user within the application.

Example: An article slug or URL.


2. onCheckoutCompletedUrl

The URL to which the user is redirected after successfully completing the checkout process.
This ensures they return to their original site or workflow and are automatically logged in.


3. callBackUrl

The URL to which the user is redirected if they cancel the checkout process.
It takes the user back to the original page or site they came from, allowing them to resume their previous activity.

Changelog

GET /api/v1/members/profile/info-with-active-subscriptions

  • Response Update:
    • Removed countryCode.
    • Returned phone along with the country calling code.
    • Example:
      {
      "phone": "+4793155389"
      }