Authentication EverReal implements OAuth 2.1 authentication standard on top of its APIs. Before you can use our SSO API, everreal has to generate a client_id and client_secret for the SSO.
Requirements
EverReal APIs supports jwt tokens using Bearer token according to RFC-7519 . This allows us to protect our information and make sure, who is requesting has correct authorization to execute the operation.
OAuth 2.0 Password Grant
Important! You should use the password grant only in server-to-server communication, where you completely trust the client.
This allows you to use the username and password to get the refresh_token
. After refresh_token
is obtain, username and password is not needed.
Authentication
POST
https://{custom_subdomain}.everreal.co/accounts/oauth/token
Request Body
Name Type Description {
"username": "john.doe@everreal.co",
"password": "Password",
"client_id": "<Client_iD>",
"client_secret": "<Client Secret>",
"scope": "offline_access *",
"grant_type": "password"
}
200 403
Copy {
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjYTdhZDI2MC1mNmE3LTQ1OWEtOWNjYy1kNTMzMzNjY2M1Y2EiLCJzdWIiOiI3NmFmY2FiMC02NTJiLTQ1NDctODAxYi03YzcwMWMwOTdiODEiLCJleHAiOjE2Mjg1OTYyNTYsImlhdCI6MTYyODU5MjY1Nn0.nnBmf0r7oTsqDYxwkA9seO-aZGhLY3z-ZodFn2NSa9gPOxCCtXvACj7UNIifd03KbqLDiJcpqj5anUzyKpXY0taXRCPMVHB78iVYDyKR8rZqNZ7PP8XSXvxxLaZPfTiqYG01pzCgaDWHwgpUsBoFRJDr2rPt1ShD6Pe-efcZIQfS81jGUAw4dYAwnot6zNC6uNY8OkihEUEwnsVI1mCfjvmrWL6cHmL-YSko-gPUGAjF1ulSJZ68CcMTrsC2tXnWLAMyiJMu9_VWoLXUgQJH2FzISeJkyPCJbnzDlMmAYfe8Kq0z8QL_l2q_cs2aOAvre-jJpyri-dsP-6hR2ODL4g",
"refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI2ZWU5YzFhNi1hMWM5LTQwOWQtYjJjOS03NjdlZGRlMzAwNDQiLCJzdWIiOiI3NmFmY2FiMC02NTJiLTQ1NDctODAxYi03YzcwMWMwOTdiODEiLCJleHAiOjE2MzExODQ2NTYsImlhdCI6MTYyODU5MjY1Nn0.IcdmncHIE3PTxix5QS5bZAm3JsPDprRqyEU6pEk09mViV-V9F8EWlYofDuQglfB5vNe_oBzZWmu3wdxGm7hO-9Z_sveI6OEBy-mv_-bHarIRytToH7zjSkl4BO_l-s48hwxGVYyQLtFX1G9vU-ykJ4Bwd4M6V1Z-0gwW65MCFn6CXgAz8lXgDLoLorwoxGjZVMKFmjNQcNLLdcLXDNXXYdU6d2bjJQLz6hzixbqhUFYbR6hZUbEJ6cBZsKWZjsvDydtJ9froWR3d4C4tbYkirmSGvZHjvtwVrjKnoHtAd0MQ8UVTKxrH7jTcATrCmWDaxyW2XFcd7HtuI3_TdQH8aw",
"expires_in": 3600,
"token_type": "Bearer"
}
Copy {
"error": "invalid_grant",
"error_description": "heimdall.validation.user.does.not.exist"
}
Make sure to store the refresh_token
securely.
Currently the refresh_token
has an expiration between 4 weeks and 2 years, it is configurable
by EverReal for each customer. After it expires you need to re-authenticate with username and
password
The access_token
expires by default every hour, but also can be configurable by EverReal to
have another expiration time (it is described by the expires_in
property). Use the
refresh_token
to generate a new one if you get an unauthorized response
Bellow you can see some examples to get token correctly.
Bash C#(RestSharp) JS Python
Copy curl --location --request POST 'https://{custom_subdomain}.everreal.co/accounts/oauth/token' \
--header 'Content-Type: application/json' \
--header 'Cookie: accept-language=de-DE' \
--data-raw '{
"username": "john.doe@everreal.co",
"password": "Password",
"client_id": "<Client_iD>",
"client_secret": "<Client Secret>",
"scope": "offline_access *",
"grant_type": "password"
}'
Copy var client = new RestClient ( $"https://{custom_subdomain}.everreal.co/accounts/oauth/token" );
client . Timeout = - 1 ;
var request = new RestRequest ( Method . POST );
request . AddHeader ( "Content-Type" , "application/json" );
request . AddHeader ( "Cookie" , "accept-language=de-DE" );
var body = @"{
" + "\n" +
@"""username"": ""john.doe@everreal.co"",
" + "\n" +
@"""password"": ""Password"",
" + "\n" +
@"""client_id"": ""<Client_iD>"",
" + "\n" +
@"""client_secret"": ""<Client Secret>"",
" + "\n" +
@"""scope"": ""offline_access *"",
" + "\n" +
@"""grant_type"": ""password""
" + "\n" +
@"}" ;
request . AddParameter ( "application/json" , body , ParameterType . RequestBody );
IRestResponse response = client . Execute (request);
Console . WriteLine ( response . Content );
Copy var axios = require ( 'axios' );
var data = JSON .stringify ({
"username" : "john.doe@everreal.co" ,
"password" : "Password" ,
"client_id" : "<Client_iD>" ,
"client_secret" : "<Client Secret>" ,
"scope" : "offline_access *" ,
"grant_type" : "password"
});
var config = {
method : 'post' ,
url : `https://{custom_subdomain}.everreal.co/accounts/oauth/token` ,
headers : {
'Content-Type' : 'application/json' ,
'Cookie' : 'accept-language=de-DE'
} ,
data : data
};
axios (config)
.then ( function (response) {
console .log ( JSON .stringify ( response .data));
})
.catch ( function (error) {
console .log (error);
});
Copy import requests
import json
url = "https:// {custom_subdomain} .everreal.co/accounts/oauth/token"
payload = json . dumps ({
"username" : "john.doe@everreal.co" ,
"password" : "Password" ,
"client_id" : "<Client_iD>" ,
"client_secret" : "<Client Secret>" ,
"scope" : "offline_access *" ,
"grant_type" : "password"
})
headers = {
'Content-Type' : 'application/json' ,
'Cookie' : 'accept-language=de-DE'
}
response = requests . post (url, headers = headers, data = payload)
print (response.text)
client_id and client_secret are parameter provided by EverReal
Oauth2.0 Authorization Code Flow
Important! Use the Authorization Code Flow in not trusted environments, like Web or Mobile app clients. Below are the necessary endpoints for the Authorization Code Flow.
Copy authorizationUri="https://${subdomain}.everreal.co/accounts/dialog/authorize"
accessTokenUri="https://${subdomain}.everreal.co/accounts/oauth/token"
tokenInfoUri="https://${subdomain}.everreal.co/accounts/api/tokeninfo?access_token={token}"
revokeTokenUri="https://${subdomain}.everreal.co/accounts/api/tokenrevoke?token={token}"
userInfoUri="https://${subdomain}.everreal.co/accounts/api/userinfo"
A basic next.js example can be over our github page https://github.com/EverRealGMBH/everreal-nextjs-nextauth-oauth2-example :
Next.js example
Read more here: https://next-auth.js.org/v3/configuration/providers#using-a-custom-provider
Copy {
id: "everreal",
name: "EverReal",
type: "oauth",
version: "2.0",
scope: "offline_access *",
params: { grant_type: "authorization_code" },
accessTokenUrl: `https://${subdomain}.everreal.co/accounts/oauth/token`,
requestTokenUrl: `https://${subdomain}.everreal.co/accounts/oauth/token`,
authorizationUrl: `https://${subdomain}.everreal.co/accounts/dialog/authorize`,
profileUrl: `https://${subdomain}.everreal.co/accounts/api/userinfo`,
async profile(profile, tokens) {
return {
...profile
}
},
clientId: "provided by everreal",
clientSecret: "provided by everreal"
}
Refresh access_token API endpoint
Refresh token in case it expires
POST
https://{custom_subdomain}.everreal.co/accounts/oauth/token
Refresh the access_token
in case it expires
Request Body
Name Type Description {
"grant_type":"refresh_token",
"client_id": "{secret}",
"client_secret": "{secret}",
"refresh_token":"{refresh_token}"
}
200
Copy {
"access_token" : "NEW TOKEN" ,
"expires_in" : "3600"
}
Use the access_token
to authenticate to any protected endpoint by passing it to the “Authorization” header like this: “Authorization: Bearer MY_ACCESS_TOKEN”
User information
GET
https://{custom_subdomain}.everreal.co/accounts/api/users/me
Based on Bearer token provided in header request, it will retrieve user information and all information about it.
200
Copy {
"id" : "76dccab0-652e-4543-802c-7c701c098ad3" ,
"email" : "john.doe@ovooovo.com" ,
"isActive" : true ,
"firstName" : null ,
"lastName" : null ,
"profilePhoto" : null ,
"profileData" : {
"language" : "en-US"
} ,
"isTenant" : false ,
"createdAt" : "2021-07-19T14:21:50.215Z" ,
"updatedAt" : "2021-07-19T14:21:50.215Z" ,
"areTermsAccepted" : true ,
"companies" : [
{
"id" : "76dccab0-652e-4543-802c-7c701c0b3bb3" ,
"name" : "automation-reporting-qa" ,
"isDefault" : true
}
] ,
"currentCompany" : {
"id" : "76dccab0-652e-4543-802c-7c701c0b3bb3" ,
"name" : "automation-reporting-qa" ,
"partner" : {
"id" : "76dccab0-652e-4543-802c-7c701c046579" ,
"name" : "test-documentation" ,
"subdomain" : "test-documentation"
} ,
"isDefault" : true
} ,
"tokenInfo" : {
"audience" : "76dccab0-652e-4543-802c-7c701c0a68f6" ,
"scope" : [
"offline_access" ,
"company_contracting_edit_contract" ,
"message_templates_all" ,
"company_portfolio_all" ,
"company_user" ,
"email_templates_all"
] ,
"user_id" : "76dccab0-652e-4543-802c-7c701c097b81" ,
"expires_in" : 3571
}
}