OAuth 2.0 Integration Guide

Introduction

This document outlines the process for transitioning from direct credential collection to a more secure OAuth 2.0 Authorization Code flow with PKCE (Proof Key for Code Exchange).
PKCE adds an additional security layer that protects against authorization code interception attacks.

Easee supports OAuth 2.0 based on the OAuth 2.0 Authorization Framework (RFC 6749) and follows the standard authorization code flow for user-delegated access. You can read more about this here

Use Cases

Easee recommends the use of OAuth2 primarily for integrations that require read-only access to Easee charging consumption data, or where the integration needs to view or update the operator assigned to a site, as part of an onboarding flow.

If you wish to control an Easee asset, please sign up to become an operator here.

Current method

Currently, partners collect user credentials in their web portals and use our login endpoint to obtain access tokens. This approach poses security risks as it requires partners to handle sensitive user credentials.

New method

The new authentication flow will:

  1. Generate PKCE code verifier and challenge
  2. Redirect users to our authentication server with the code challenge
  3. Allow users to authenticate directly with our system
  4. The user will be prompted to consent to granting the requested level of access. They can withdraw this consent at any time via Easee Cloud.
  5. Redirect users back to the partner portal with an authorization code
  6. Enable partners to exchange this code for an access token using the original code verifier

Implementation guide

Step 1: Client registration

Before implementation, please fill in this form so we can register your application as an OAuth client in our system.

You will then receive:

  • Client id
  • Client secret (if the client is confidential)

Step 2: Generate PKCE code verifier and challenge

  1. Generate a cryptographically random code verifier (between 43-128 characters):
    • Use only unreserved URL characters: A-Z ,a-z, 0-9 , - , ., _ , and ~
  2. Generate a code challenge from the code verifier:
    • Apply SHA-256 hash to the code verifier
    • Base64-URL encode the hash value
    • Remove padding ( = characters)

Step 3: Authorization request with PKCE

Redirect the user to our authorization endpoint with the code challenge:

GET https://auth.easee.com/realms/easee/protocol/openid-connect/auth

With the following parameters:

client_id=[your-client-id]
response_type=code
redirect_uri=[your-registered-redirect-uri]
scope=openid profile email
code_challenge=[code-challenge-from-step-2]
code_challenge_method=S256

Example:

https://auth.easee.com/realms/easee/protocol/openid-connect/a?client_id=public-test-partner
&response_type=code
&redirect_uri=https://test-partner.com/callback
&scope=openid+profile+email
&code_challenge=l7JZX44KWMYNUMF2ISldjbaQa_lTBU9bdx8wdB7YXeg
&code_challenge_method=S256

OAuth Scopes

The scope parameter defines the permissions your application is requesting from the user.

In addition to the standard OpenID Connect scopes (openid, profile, and email), Easee provides API-specific scopes that grant access to chargers, charging control, sites, sessions, equalizers, and other resources.

Applications should request only the permissions required for their functionality.

For a complete list of available scopes and their associated permissions, see the Available Scopes documentation.

Step 4: User authentication

The user will authenticate directly with our system.

Step 5: Authorization code return

After successful authentication, the user will be redirected back to your redirect_uri with an authorization code:

https://partner.com/callback?code=SplxlOBeZQQYbYS6WxSbIA&state=a1b2c3d4e5

Step 6: Token exchange with code verifier

Exchange the authorization code for an access token by including the original verifier:

POST https://auth.easee.com/realms/easee/protocol/openid-connect/token
Content-Type: application/x-www-form-urlencoded

With the following parameters:

grant_type=authorization_code
code=[authorization-code-from-step-5]
redirect_uri=[same-redirect-uri-used-in-step-3]
client_id=[your-client-id]
code_verifier=[code-verifier-from-step-2]

If using a confidential client, also include:

client_secret=[your-client-secret]

Step 7: Using the access token

The response will include:

{
"access_token": "ey...",
"expires_in": 3600,
"refresh_token": "ey...",
"refresh_expires_in": 86400,
"token_type": "Bearer",
"id_token": "ey...",
"not-before-policy": 0,
"session_state": "Se..."
"scope": "openid profile email"
}

Use the access token in API requests by including it in the Authorization header:

Authorization: Bearer [access_token]

Step 8: Token refresh

When the access token expires, use the refresh token to obtain a new one:

POST https://auth.easee.com/realms/easee/protocol/openid-connect/token
Content-Type: application/x-www-form-urlencoded

With the following parameters:

grant_type=refresh_token
refresh_token=[refresh-token]
client_id=[your-client-id]

If using a confidential client, also include:

client_secret=[your-client-secret]

Token Lifetimes and offline_access Scope

Default Session (No offline access)

When using the standard Authorization Code flow without requesting the offline_access scope:

  • Access token lifetime: 1 hour
  • Refresh token lifetime: 24 hours
  • Maximum session lifespan: 60 days

This means:

  • The client must use the refresh token within 24 hours, otherwise it expires and the user must log in again.
  • Even if the client refreshes the access token regularly (e.g., daily), the session will expire after 60 days of continuous use, requiring the user to reauthenticate.

This configuration is intended for:

  • Web applications requiring periodic user interaction
  • Partner integrations where a short-lived delegated action is required (e.g, a partner setting the operator on behalf of the customer, before taking control with their operator account)

With offline access

When the offline_access scope is requested and granted:

  • Access token lifetime: 1 hour (unchanged)
  • Refresh token lifetime: Up to 90 days
  • Maximum session lifespan: Unlimited (Providing it's refreshed once within the 90 day refresh token window)

This means:

  • As long as the client uses the refresh token at least once every 90 days, the session remains valid.
  • There is no enforced maximum session duration; the session can continue indefinitely through token refresh unless access is revoked.
  • If the refresh token is not used within the 90-day window, it expires and the user must log in again.

This configuration is intended for:

  • Mobile applications
  • Long-lived backend integrations
  • Partners requiring persistent access without repeated user interaction

Example request with offline_accessscope

https://auth.easee.com/realms/easee/protocol/openid-connect/auth?client_id=public-test-partner
&response_type=code
&redirect_uri=https://test-partner.com/callback
&scope=openid+profile+email+offline_access
&code_challenge=l7JZX44KWMYNUMF2ISldjbaQa_lTBU9bdx8wdB7YXeg
&code_challenge_method=S256
📘

Please Note: It is not recommended to ask for the offline_access scope if it is not needed for your particular use case.


Did this page help you?