Sign-in using the Hybrid Flow
This tutorial will help you to sign-in using the Hybrid Flow.
If you want to learn how the flow works and why you should use it, see OpenID Hybrid Flow.
Prerequisites
Before beginning this tutorial:
Create an App to retrieve a Client ID and Client Secret. These APP credentials identify your app during the authorization process.
- Log in to your Partner Dashboard.
- Click Apps.
- Click "Add an app" to open Developers Dashboard.
- Click Create App.
- Enter the App name, add an Allowed Redirect URL of https://YOUR_APP/callback.
- Click Create.
- View your
Client ID
andClient Secret
(need re-enter your password).
Steps
- Authorize user: Request the user's authorization and redirect back to your app with an authorization code.
- Request tokens: Exchange your authorization code for tokens.
- Call API: Use the retrieved Access Token to call API.
- Refresh tokens: Use a Refresh Token to request new tokens when the existing ones expire.
- ID Token Structure
- Validate ID Tokens
- Library example configuration
Authorize user
To begin the flow, you'll need to get the user's authorization. This step may include one or more of the following processes:
- Authenticating the user;
- Redirecting the user to an Identity Provider to handle authentication;
- Checking for active Single Sign-on (SSO) sessions;
- Obtaining user consent for the requested permission level, unless consent has been previously given.
To authorize the user, your app must send the user to the authorization URL (open url on browser).
Authorization URL:
https://accounts.haravan.com/connect/authorize?response_mode=form_post&response_type=YOUR_RESPONSE_TYPE&scope=YOUR_SCOPE&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&state=YOUR_STATE&nonce=YOUR_NONCE&orgid=ORG_ID
Parameters
Note that for authorizing a user when calling a custom API, you can include additional scopes supported by the target API.
Parameter Name | Description |
---|---|
response_mode | Specifies the method with which response parameters should be returned. For security purposes, the value should be form_post . In this mode, response parameters will be encoded as HTML form values that are transmitted via the HTTP POST method and encoded in the body using the application/x-www-form-urlencoded format. |
response_type | For this flow, the value must include code and id_token . |
scope | Specifies the scopes for which you want to request authorization, which dictate which claims (or user attributes) you want returned. These must be separated by a space. You can request any of the standard OpenID Connect (OIDC) scopes about users, such as profile or email , or any scopes supported by the target API (e.g., com.read_products ). Include offline_access to get a Refresh Token.Ex: scope=openid profile email org userinfo |
client_id | Your application's Client ID. |
redirect_uri | The URL to which Haravan will redirect the browser after authorization has been granted by the user. The Authorization Code will be available in the code URL parameter. You must specify this URL as a valid Redirect Url in your Application Settings.The redirect URI must begin with the scheme https. There are some exceptions for localhost redirect URIs. Warning: Per the OAuth 2.0 Specification, Haravan removes everything after the hash and does not honor any fragments. |
state | (recommended) An opaque arbitrary alphanumeric string your app adds to the initial request that Haravan includes when redirecting back to your application. Use this value to prevent cross-site request forgery (CSRF) attacks. |
nonce | A cryptographically random string that your app adds to the initial request and Haravan includes inside the ID Token, used to prevent token replay attacks. |
orgid | (optional) ID of the organization to use when authenticating a user. When not provided, the user will be able to select the organization when authenticating. - OrgID is field id in https://{organization-store-name}.myharavan.com/meta.json - Use this parameter to force user login in a specific organization. |
As an example, your HTML snippet for your authorization URL when adding login to your app might look like:
<a href="https://accounts.haravan.com/connect/authorize?response_mode=form_post&response_type=code id_token&scope=openid profile email org userinfo offline_access&client_id=YOUR_CLIENT_ID&redirect_uri=https://YOUR_APP/callback&state=YOUR_STATE&nonce=YOUR_NONCE">
Sign In
</a>
Login permissions prompt. Haravan shows the following prompt to receive authorization from the user.
Response
If all goes well, you'll receive an HTTP POST
form. The requested credentials are encoded in the body:
POST HTTP/1.1
Content-Type: application/x-www-form-urlencoded
code=AUTHORIZATION_CODE&
id_token=eyJhb...WVkDuuKNw&
scope=openid profile email org userinfo offline_access&
state=YOUR_STATE&
session_state=u...BAA5AEB
Example: receive a successful form
Example: receive an error form
Haravan will also return any state value you included in your call to the authorization URL.
You should validate your tokens before saving them. To learn how, see Validate ID Tokens.
If your application only needs to use Hybrid Flow for sign-on, you will not need an Access Token, only an ID Token with claims. and you can skip next step.
Request tokens
Now that you have an Authorization Code, you must exchange it for tokens. Using the extracted Authorization Code (code
) from the previous step, you will need to POST
to the token URL /connect/token
.
The Access Token you receive in this step is the one you should use to call your API.
Example POST to token URL
curl --request POST \
--url 'https://accounts.haravan.com/connect/token' \
--header 'content-type: application/x-www-form-urlencoded' \
--data 'grant_type=authorization_code' \
--data 'client_id=YOUR_CLIENT_ID' \
--data 'client_secret=YOUR_CLIENT_SECRET' \
--data 'code=YOUR_AUTHORIZATION_CODE' \
--data 'redirect_uri=https://YOUR_APP/callback'
Parameter Name | Description |
---|---|
grant_type | Set this to authorization_code |
code | The authorization_code retrieved in the previous step of this tutorial. |
client_id | Your application's Client ID. You can find this value in your Application Settings. |
client_secret | Your application's Client Secret. You can find this value in your Application Settings. |
redirect_uri | The valid callback URL set in your Application settings. This must exactly match the redirect_uri passed to the authorization URL in the previous step of this tutorial. Note that this must be URL encoded. |
Response
If all goes well, you'll receive an HTTP 200
response with a payload containing access_token
, id_token
, token_type
, and (optional) refresh_token
values:
{
"id_token": "eyJh...Mqqg",
"access_token": "C5BD...3009",
"expires_in": 86400,
"token_type": "Bearer",
"refresh_token": "C2ED...2500",
"scope": "openid profile email org userinfo offline_access"
}
Parameter Name | Description |
---|---|
id_token | A JSON Web Token (JWT). The app can decode the segments of this token to request information about the user who signed in. The app can cache the values and display them, and confidential clients can use this for authorization. |
access_token | The requested access token. The app can use this token to authenticate to the secured resource, such as userinfo or a web API. |
expires_in | How long the access token is valid (in seconds). |
token_type | Indicates the token type value. The only type that Haravan supports is Bearer |
refresh_token | An OAuth 2.0 refresh token. The app can use this token acquire additional access tokens after the current access token expires. Refresh_tokens are long-lived, and can be used to retain access to resources for extended periods of time. Note: Only provided if offline_access scope was requested. |
scope | The scopes that the access_token is valid for. |
Example
You should validate your tokens before saving them. To learn how, see Validate ID Tokens.
ID Token contain user information that must be decoded and extracted.
Access Tokens are used to call the Haravan Authentication API's /connect/userinfo endpoint or another API.
Refresh Tokens are used to obtain a new Access Token or ID Token after the previous one has expired. The refresh_token
will only be present in the response if you included the offline_access
scope for your API.
Refresh Tokens must be stored securely since they allow a user to remain authenticated essentially forever.
Call API
To call API from a regular web application (or similar cases in which the Client Secret can be safely stored), the application must pass the retrieved Access Token as a Bearer token in the Authorization header of your HTTP request.
Example: GET userinfo endpoint
curl --request GET \
--url https://accounts.haravan.com/connect/userinfo \
--header 'authorization: Bearer ACCESS_TOKEN' \
--header 'content-type: application/json'
Example: GET products.json endpoint. The scopes must include com.read_products and enabled in your Application Settings.
curl --request GET \
--url https://apis.haravan.com/com/products.json \
--header 'authorization: Bearer ACCESS_TOKEN' \
--header 'content-type: application/json'
Refresh tokens
You have already received a Refresh Token if you've been following this tutorial and included the offline_access
scope when you initiated the authentication request through the authorize endpoint.
You can use the Refresh Token to get a new Access Token. Usually, a user will need a new Access Token only after the previous one expires or when gaining access to a new resource for the first time. It's bad practice to call the endpoint to get a new Access Token every time you call an API, and Haravan maintains rate limits that will throttle the amount of requests to the endpoint that can be executed using the same token from the same IP.
To refresh your token, make a POST
request to the /connect/token
endpoint in the Authentication API, using grant_type=refresh_token
.
Example POST to token URL
curl --request POST \
--url 'https://accounts.haravan.com/connect/token' \
--header 'content-type: application/x-www-form-urlencoded' \
--data 'grant_type=refresh_token' \
--data 'client_id=YOUR_CLIENT_ID' \
--data 'client_secret=YOUR_CLIENT_SECRET' \
--data 'refresh_token=YOUR_REFRESH_TOKEN'
Parameter Name | Description |
---|---|
grant_type | Set this to refresh_token . |
client_id | Your application's Client ID. You can find this value in your Application Settings. |
client_secret | Your application's Client Secret. You can find this value in your Application Settings. |
refresh_token | The Refresh Token to use. |
If all goes well, you'll receive an HTTP 200
response with a payload containing a new access_token
, its lifetime in seconds (expires_in
), granted scope
values, token_type
, new id_token
, and new refresh_token
:
{
"id_token": "eyJh...Yyzw",
"access_token": "3BDD...A3FF",
"expires_in": 86400,
"token_type": "Bearer",
"refresh_token": "C2ED...2500",
"scope": "openid profile email org userinfo offline_access"
}
You should validate your tokens before saving them. To learn how, see Validate ID Tokens.
Refresh token lifetime: Refresh tokens have a significantly longer lifetime than access tokens. The default lifetime for the Refresh tokens is 30 days and they replace themselves with a fresh token upon every use. This means that whenever a refresh token is used to acquire a new access token, a new refresh token is also issued. Securely delete the old refresh token after acquiring a new one. Refresh tokens need to be stored safely like access tokens or application credentials.
Notes: new refresh_token may be the same value as old refresh_token, but may be different in the future, alway store new refresh_token.
Refresh tokens can be revoked at any time, because of timeouts and revocations. Your app must handle rejections by the sign-in service gracefully when this occurs. This is done by sending the user to an interactive sign-in prompt to sign in again.
ID Token Structure
ID tokens are JSON web tokens (JWT). These ID tokens consist of a header, payload, and signature. The header and signature are used to verify the authenticity of the token, while the payload contains the information about the user requested by your client.
Payload parameters
Parameter Name | Description |
---|---|
nbf | A UNIX timestamp. When the token activates. |
exp | A UNIX timestamp. When the token expires. |
iss | An issuer URI. Identifies the issuer, or "authorization server" that constructs and returns the token. |
aud | Client ID |
nonce | The nonce matches the parameter included in the original /authorize request to the IDP. If it does not match, your application should reject the token. |
iat | A UNIX timestamp. When the token was issued. |
sid | A unique session ID per user and app. |
idp | Records the identity provider that authenticated the subject of the token. This value is identical to the value of the Issuer claim. |
orgid | Organization ID |
orgname | Organization name |
orgcat | Organization's category |
sub | User id, The user that the session token is intended for. |
User's email | |
name | User's name |
middle_name | User's middle_name |
role | User's roles |
locale | User's locale |
Validate ID Tokens
An ID token, which contains user profile attributes, is consumed by an app and is typically used for user interface display. Haravan issues all ID tokens in JSON web token (JWT) format.
If any of these checks fail, the token is considered invalid, and the request must be rejected.
Validate the JWT.
- We strongly recommend that you use middleware or one of the existing open source third-party libraries to parse and validate JWTs. At JWT.io, you can find libraries for various platforms and languages, such as .NET, Python, Java, Ruby, Objective-C, Swift, Nodejs, and PHP.
- To verify the signature of a token from one of your applications, we recommend that you get the
Public Key
from Haravan JWKS: https://accounts.haravan.com/.well-known/openid-configuration/jwks
Check additional standard claims. If you've performed the standard JWT validation, you have already decoded the JWT's Payload and looked at its standard claims. Additional claims to verify for ID tokens include:
- Token audience (
aud
, string): The audience value for the token must match the Client ID of the application as defined in your Application's Settings in the Client ID field. - Nonce (
nonce
, string): Passing a nonce in the token request is recommended (required for the Implicit Flow) to help prevent replay attacks. The nonce value in the token must exactly match the original nonce sent in the request. - Token expiration (
exp
, Unix timestamp): The expiration date/time must be after the current date/time. - Token issuer (
iss
, string): The issuing authority inside the token must match the issuing authority (issuer
) identified in Haravan discovery document, which exists at
https://accounts.haravan.com/.well-known/openid-configuration
- Token audience (