OAuth integration with Subrite OIDC
Let users sign in to your application with their Subrite account through the OIDC web application flow with PKCE: redirect to the login page, exchange the code for tokens, refresh tokens, log out, and call the member API.
Subrite provides the 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 in the Subrite Admin Portal. You will receive a client ID, client secret, and redirect URI for your application. Once you have the required parameters, follow the steps below to enable OAuth login.
Subrite OIDC follows the PKCE standard, so you need to add code_challenge_method and code_challenge when you make the very first request to authenticate. If you use a standard library to generate the code, you also need to keep the code_verifier so you can use it later to get access tokens.
Required parameters
- Client ID (
client_id) - Client secret (
client_secret) - Redirect URI (
redirect_uri)
OIDC client configuration options
When registering your OIDC client in the Subrite Admin Portal, you can configure the following options.
Disable signup
The Disable signup option prevents new user registration through the OIDC authentication flow. When it is enabled:
- Users are always directed to the sign-in page (never sign-up).
- The sign-up link is hidden on the sign-in page.
- Only users with existing accounts can authenticate.
This is useful for:
- Apple Reader App compliance (Apple requires that reader apps do not allow new user creation through authentication).
- Applications that require users to have pre-existing accounts.
- Scenarios where user registration should be handled through a separate process.
Flow steps
- Users are redirected to the Subrite OIDC login page.
- Users are authenticated.
- Users are redirected to the registered redirect URI.
Environment URLs
- Stage URL: will be provided once it is prepared.
- Production URL: will be provided once it is prepared.
Step 1: Redirect to the 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 because PKCE is enabled. |
code_challenge | Yes | string | Base64 encoded SHA256 hash of a long character string. |
scope | Yes | string | openid, offline_access |
state | No | string | An opaque value, used for security purposes. Can encode JSON with action: "signup" to direct users to the registration page. If this parameter is set in the request, 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 is thrown.
Example:
redirect_uri=http%3A%2F%2Flocalhost%3A3010%2Fcallback,http%3A%2F%2Flocalhost%3A3010%2Falt-callbackDirect users to signup
To direct users to the registration (signup) page instead of the login page, encode the action in the state parameter.
Example use case: if your application has a "Subscribe" or "Sign Up" button, encode {"action":"signup"} in the state parameter:
# state={"action":"signup"} URL encoded to %7B%22action%22%3A%22signup%22%7D
http://{{subriteUrl}}/api/oidc/auth?client_id=your-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=%7B%22action%22%3A%22signup%22%7DYou can combine the signup action with CSRF protection:
{
"action": "signup",
"csrf": "your-csrf-token"
}Example request URLs
For the login flow:
http://{{subriteUrl}}/api/oidc/auth?client_id=your-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=csrf-tokenFor the signup flow:
# state={"action":"signup"} URL encoded
http://{{subriteUrl}}/api/oidc/auth?client_id=your-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=%7B%22action%22%3A%22signup%22%7DStep 2: The user authenticates
Once the user completes the request in Step 1, they are 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 is redirected to the registered
redirect_uri. - The response contains:
- A temporary authorization code (
code). - The state parameter (if provided in the initial request).
- A temporary authorization code (
Step 3: Exchange the code for a token
When the user comes back to your redirect_uri, read the code from the request URL. Then make a POST request to the token endpoint with the following parameters:
codecode_verifiergrant_typeclient_idclient_secret
You get the code_verifier when you generate the code_challenge in Step 1. The token endpoint responds with an access token and a refresh token.
Token endpoint
POST /api/oidc/tokenHeaders
Content-Type: application/x-www-form-urlencoded
Accept: application/jsonRequired parameters
| Parameter | Required | Type | Description |
|---|---|---|---|
grant_type | Yes | string | authorization_code |
client_id | Yes | string | Your Client ID. |
client_secret | Yes | string | Your Client Secret. |
code | Yes | string | The code you received in the code parameter in Step 2. |
code_verifier | Yes | string | The code verifier stored in the session when you generated code_challenge in Step 1. |
Response
{
"token_type": "<string>",
"expires_in": <integer>,
"access_token": "<string>",
"refresh_token": "<string>",
"id_token": "<string>",
"scope": "<string>"
}Use the access token to call the Subrite API
Once you have the access token, 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
{
"id": "string", // Updated: memberId is now a string,Ex: "1", "c29a724f-36cf-4584-9d47-1cdde8733f75" etc
"fullName": "string",
"email": "string",
"userType": "system_admin",
"userId": 1234,
"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",
"hasAccess": true
}
],
"customPropertyValues": {
"muscNumber": 1234,
"localClub": "",
"mufcNumber": 1234568,
"mufcExpiration": "2023-12-27T18:00:00.000Z"
}
}
]
}Refresh the access token
To get a new access token with the refresh token, use the same token endpoint with grant_type set to refresh_token.
Token endpoint
POST /api/oidc/tokenHeaders
Content-Type: application/x-www-form-urlencoded
Accept: application/jsonRequired parameters
| Parameter | Required | Type | Description |
|---|---|---|---|
grant_type | Yes | string | refresh_token |
client_id | Yes | string | Your Client ID. |
client_secret | Yes | string | Your Client Secret. |
refresh_token | Yes | string | The refresh token you received in Step 3. |
Example request

Logout
When you register your application in the Subrite Admin Portal, you also provide a post_logout_redirect_uri. When implementing logout in your application, you must make sure 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 then redirects back to your application's configured
post_logout_redirect_uri.
- Log out from your application.
Subrite logout endpoint
To log out from Subrite, make a GET request to:
GET /api/oidc/session/endYou can also specify which client you are signing out from:
GET /api/oidc/session/end?client_id=your_client_idPost logout redirection
After logging out from Subrite, the user is redirected to the configured post_logout_redirect_uri.
PHP sample code
Send the login request to Subrite OIDC
public function login(Request $request, $isSignup = false)
{
$codeVerifier = bin2hex(random_bytes(64));
$codeChallenge = rtrim(strtr(base64_encode(hash('sha256', $codeVerifier, true)), '+/', '-_'), '=');
// Encode signup intent in state parameter
if ($isSignup) {
$state = json_encode(['action' => 'signup']);
} else {
$state = \bin2hex(\random_bytes(16)); // Regular CSRF token
}
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);
}Request the access token
After receiving the authorization code in the callback, make a request to the token endpoint to exchange it for an access token.
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();
}Member information and access APIs
Get logged-in member info with content access
Retrieve detailed information about the logged-in member, including their content access rights.
More details are in the API reference: Get logged-in member info with content access
Get logged-in member info with active subscriptions
Retrieve detailed information about the logged-in member, including their active subscriptions.
More details are in the API reference: Get logged-in member info with active subscriptions
Checkout search parameters
You can add these search parameters when you send a user to the checkout page.
| Parameter | Description |
|---|---|
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. |
onCheckoutCompletedUrl | The URL the user is redirected to after successfully completing the checkout process. This ensures they return to their original site or workflow and are automatically logged in. |
callBackUrl | The URL the user is redirected to if they cancel the checkout process. It takes the user back to the original page or site they came from, so they can resume their previous activity. |
Changelog
GET /api/v1/members/profile/info-with-active-subscriptions
Response update:
- Removed
countryCode. phoneis now returned with the country calling code, for example:
{
"phone": "+4793155389"
}