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
- Users will be redirected to Subrite OIDC login page
- Users will be authenticated
- 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
Parameter | Required | Type | Description |
---|---|---|---|
response_type | Yes | string | Grant to execute. Only code is currently supported. |
client_id | Yes | string | Your Client ID. |
redirect_uri | Yes | string | A successful response from this endpoint results in a redirect to this URL. Must include all registered redirect URIs. |
code_challenge_method | Yes | S256 | Required as we have PKCE enabled. |
code_challenge | Yes | string | Base64 encoded SHA256 hashed long character string. |
scope | Yes | string | openid , offline_access |
state | No | string | An 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_uri
s to a single client ID in Subrite, every request must include a redirect_uri
.
If multiple redirect_uri
s 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).
- A temporary authorization code (
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
Parameter | Required | Type | Description |
---|---|---|---|
grant_type | required | string | authorization_code |
client_id | required | string | Your Client ID. |
client_secret | required | string | Your Client Secret. |
code | required | string | The code you received as a response in code parameter in Step 2. |
code_verifier | required | string | Code 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
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:
- Stage: https://stage.api.subrite.no
- Production: https://api.subrite.no
Response Sample
subscriptions: Only returns active subscriptions.
Ifsubscriptions.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
Parameter | Required | Type | Description |
---|---|---|---|
grant_type | required | string | refresh_token |
client_id | required | string | Your Client ID. |
client_secret | required | string | Your Client Secret. |
refresh_token | required | string | The 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
-
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
.
-
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();
}
4. Member Information, Content, Consent, and Subscription Access APIs
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"
}
- Removed