Skip to main content

Authentication API

Overview

EverShop uses JWT (JSON Web Tokens) for secure API authentication across both admin and customer endpoints. JWTs are self-contained tokens that contain encoded user information and claims, eliminating the need for session management on the server. Each token is cryptographically signed to prevent tampering and verify authenticity.

Endpoints

JWT Token Types

EverShop issues two types of tokens:

  • Access Token: Short-lived token used to authenticate API requests
  • Refresh Token: Long-lived token used to obtain new access tokens without re-authenticating

Configuration via Environment Variables

Configure JWT behavior using the following environment variables:

VariableDescriptionDefault
JWT_ADMIN_SECRETSecret key for signing and verifying admin user access tokensRequired
JWT_ADMIN_REFRESH_SECRETSecret key for signing and verifying admin user refresh tokensRequired
JWT_CUSTOMER_SECRETSecret key for signing and verifying customer access tokensRequired
JWT_CUSTOMER_REFRESH_SECRETSecret key for signing and verifying customer refresh tokensRequired
JWT_ADMIN_TOKEN_EXPIRYAdmin access token expiration (seconds)900 (15 minutes)
JWT_ADMIN_REFRESH_TOKEN_EXPIRYAdmin refresh token expiration (seconds)54,000 (15 hours)
JWT_CUSTOMER_TOKEN_EXPIRYCustomer access token expiration (seconds)1,800 (30 minutes)
JWT_CUSTOMER_REFRESH_TOKEN_EXPIRYCustomer refresh token expiration (seconds)108,000 (30 hours)
JWT_ISSUERValue written to the iss claim and verified on every tokenevershop

Integration Flow

  1. Authenticate with credentials to receive access and refresh tokens
  2. Include the access token in subsequent API requests via the Authorization: Bearer <token> header
  3. When the access token expires, use the refresh token to obtain a new one
  4. Repeat steps 2-3 to maintain continuous authenticated access
The refresh endpoints do not rotate the refresh token

/api/user/token/refresh and /api/customer/token/refresh return { "data": { "accessToken": "..." } } — a new access token only. Keep using the refresh token you already hold until it expires, then re-authenticate with credentials.

Both refresh handlers re-read the account from the database and require status = 1, so a user or customer who has been disabled since the refresh token was issued gets 401 (Admin user not found or inactive / Customer not found or inactive) instead of a fresh token.

The two token families are cryptographically separate. Access and refresh tokens are signed with different secrets, carry an explicit tokenKind (access / refresh) and an aud of admin or customer, and every claim is verified on use — presenting a refresh token where an access token is expected fails, and so does presenting a customer token to an admin route.

Get Admin User Access Token

Generates a JWT (JSON Web Token) for admin user authentication. This endpoint allows authorized administrators to obtain a secure token that can be used for subsequent API requests. The token is issued with a configurable expiration time and contains claims that identify the user as an admin.

Authentication: Requires valid admin credentials (username and password, or API key)

Use Cases:

  • Authenticate as an admin user to access restricted endpoints
  • Obtain a token for programmatic access to admin-only resources
  • Refresh or rotate admin authentication tokens
info

By default the access token is valid for 15 minutes. You can configure the token expiration time by using the JWT_ADMIN_TOKEN_EXPIRY environment variable with the desired duration in seconds. The refresh token is valid for 15 hours by default (54000 seconds) and can be configured using the JWT_ADMIN_REFRESH_TOKEN_EXPIRY environment variable.

Request Schema (application/json)
Field NameField TypeRequired
emailstringYes
passwordstringYes
POST/api/user/tokens
curl
-H "Accept: application/json"
--data-raw "<JSON DATA>"
https://<your domain>/api/user/tokens
Sample Of Response
{
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImFkbWluX3VzZXJfaWQiOjEsInV1aWQiOiJjNmM4YThmNy1iOWI4LTQzYzYtYWQyNC0zMTdjMzRmY2ZlNzIiLCJzdGF0dXMiOnRydWUsImVtYWlsIjoiYWRtaW5AYWRtaW4uY29tIiwiZnVsbF9uYW1lIjoiYWRtaW4iLCJjcmVhdGVkX2F0IjoiMjAyNC0xMi0xMFQwNzowODoyMS4wMTFaIiwidXBkYXRlZF9hdCI6IjIwMjQtMTItMTBUMDc6MDg6MjEuMDExWiJ9LCJ0b2tlblR5cGUiOiJhZG1pbiIsInRva2VuS2luZCI6ImFjY2VzcyIsImlhdCI6MTc2MjE0NDQyOCwiZXhwIjoxNzYyMTczMjI4LCJhdWQiOiJhZG1pbiIsImlzcyI6ImV2ZXJzaG9wIn0.Dsd1DvAdWOthCv_0fAlHbVmxJNHFzrQvfeMy7p-ozhU",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImFkbWluX3VzZXJfaWQiOjEsInV1aWQiOiJjNmM4YThmNy1iOWI4LTQzYzYtYWQyNC0zMTdjMzRmY2ZlNzIiLCJzdGF0dXMiOnRydWUsImVtYWlsIjoiYWRtaW5AYWRtaW4uY29tIiwiZnVsbF9uYW1lIjoiYWRtaW4iLCJjcmVhdGVkX2F0IjoiMjAyNC0xMi0xMFQwNzowODoyMS4wMTFaIiwidXBkYXRlZF9hdCI6IjIwMjQtMTItMTBUMDc6MDg6MjEuMDExWiJ9LCJ0b2tlblR5cGUiOiJhZG1pbiIsInRva2VuS2luZCI6InJlZnJlc2giLCJpYXQiOjE3NjIxNDQ0MjgsImV4cCI6MTc2MjE0NTMyOCwiYXVkIjoiYWRtaW4iLCJpc3MiOiJldmVyc2hvcCJ9.JF00yEJla1P51JRq8gRUkbnrt080f_GOeh2d8_XGqHU"
}
}

Response Properties

PropertyDescription
accessTokenJWT access token for authenticated requests
refreshTokenJWT refresh token for obtaining new access tokens

Mint Admin Tokens From A Session

Issues an admin access/refresh token pair for the admin who is already authenticated on this request — no credentials are sent and there is no request body at all.

This is the bridge between the cookie world and the token world. A script running same-origin inside the admin panel already has a valid admin session cookie but no JWT; this endpoint converts one into the other so the script can call the REST and GraphQL APIs, or hand the pair to a third-party service that will act on the admin's behalf and refresh at /api/user/token/refresh.

Authentication: Requires an existing authenticated admin — either the admin session cookie or an admin Bearer token. Unlike the other three endpoints on this page, this route is declared access: "private", so the global admin auth middleware rejects the request before the handler runs.

Request Schema (application/json)
No request body required
POST/api/user/session/tokens
curl
-H "Accept: application/json"
-H "Authorization: Bearer <admin JWT token>"
--data-raw '<JSON DATA>'
https://<your domain>/api/user/session/tokens
Sample Of Response
{
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImFkbWluX3VzZXJfaWQiOjEsInV1aWQiOiJjNmM4YThmNy1iOWI4LTQzYzYtYWQyNC0zMTdjMzRmY2ZlNzIiLCJzdGF0dXMiOnRydWUsImVtYWlsIjoiYWRtaW5AYWRtaW4uY29tIiwiZnVsbF9uYW1lIjoiYWRtaW4iLCJjcmVhdGVkX2F0IjoiMjAyNC0xMi0xMFQwNzowODoyMS4wMTFaIiwidXBkYXRlZF9hdCI6IjIwMjQtMTItMTBUMDc6MDg6MjEuMDExWiJ9LCJ0b2tlblR5cGUiOiJhZG1pbiIsInRva2VuS2luZCI6ImFjY2VzcyIsImlhdCI6MTc2MjE0NDQyOCwiZXhwIjoxNzYyMTczMjI4LCJhdWQiOiJhZG1pbiIsImlzcyI6ImV2ZXJzaG9wIn0.Dsd1DvAdWOthCv_0fAlHbVmxJNHFzrQvfeMy7p-ozhU",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImFkbWluX3VzZXJfaWQiOjEsInV1aWQiOiJjNmM4YThmNy1iOWI4LTQzYzYtYWQyNC0zMTdjMzRmY2ZlNzIiLCJzdGF0dXMiOnRydWUsImVtYWlsIjoiYWRtaW5AYWRtaW4uY29tIiwiZnVsbF9uYW1lIjoiYWRtaW4iLCJjcmVhdGVkX2F0IjoiMjAyNC0xMi0xMFQwNzowODoyMS4wMTFaIiwidXBkYXRlZF9hdCI6IjIwMjQtMTItMTBUMDc6MDg6MjEuMDExWiJ9LCJ0b2tlblR5cGUiOiJhZG1pbiIsInRva2VuS2luZCI6InJlZnJlc2giLCJpYXQiOjE3NjIxNDQ0MjgsImV4cCI6MTc2MjE0NTMyOCwiYXVkIjoiYWRtaW4iLCJpc3MiOiJldmVyc2hvcCJ9.JF00yEJla1P51JRq8gRUkbnrt080f_GOeh2d8_XGqHU"
}
}

The tokens are identical in shape, lifetime and privilege to the ones returned by POST /api/user/tokens. Treat the response as a credential: it grants the caller everything the signed-in admin can do, and the pair keeps working after the originating session cookie is cleared.

Errors

StatusWhen
401No admin session or token on the request. Also returned when the admin's roles list is restrictive and does not include the sessionTokens route id.
500Token signing failed — in practice, JWT_ADMIN_SECRET or JWT_ADMIN_REFRESH_SECRET is not configured.

Refresh Admin User Access Token

Renews the admin access token using a valid refresh token. This endpoint allows you to obtain a new access token without requiring credentials, extending your authenticated session without interruption.

Use Cases:

  • Obtain a new access token after the current one expires
  • Maintain continuous authenticated access without re-entering credentials
  • Implement seamless token rotation in your application

Authentication: Requires valid refresh token

Request Schema (application/json)
Field NameField TypeRequired
refreshTokenstringYes
POST/api/user/token/refresh
curl
-H "Accept: application/json"
--data-raw "<JSON DATA>"
https://<your domain>/api/user/token/refresh
Sample Of Response
{
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImFkbWluX3VzZXJfaWQiOjEsInV1aWQiOiJjNmM4YThmNy1iOWI4LTQzYzYtYWQyNC0zMTdjMzRmY2ZlNzIiLCJzdGF0dXMiOnRydWUsImVtYWlsIjoiYWRtaW5AYWRtaW4uY29tIiwiZnVsbF9uYW1lIjoiYWRtaW4iLCJjcmVhdGVkX2F0IjoiMjAyNC0xMi0xMFQwNzowODoyMS4wMTFaIiwidXBkYXRlZF9hdCI6IjIwMjQtMTItMTBUMDc6MDg6MjEuMDExWiJ9LCJ0b2tlblR5cGUiOiJhZG1pbiIsInRva2VuS2luZCI6ImFjY2VzcyIsImlhdCI6MTc2MjE0NDQyOCwiZXhwIjoxNzYyMTczMjI4LCJhdWQiOiJhZG1pbiIsImlzcyI6ImV2ZXJzaG9wIn0.Dsd1DvAdWOthCv_0fAlHbVmxJNHFzrQvfeMy7p-ozhU"
}
}

Get Customer Access Token

Generates JWT tokens for customer authentication. This API allows customers to securely log in and access their accounts using tokens.

Authentication: Requires valid customer credentials (email and password)

Use Cases:

  • Authenticate customers for accessing their accounts
  • Obtain tokens for programmatic access to customer-specific resources
  • Refresh or rotate customer authentication tokens
info

By default the access token is valid for 30 minutes. You can configure the token expiration time by using the JWT_CUSTOMER_TOKEN_EXPIRY environment variable with the desired duration in seconds. The refresh token is valid for 30 hours by default (108000 seconds) and can be configured using the JWT_CUSTOMER_REFRESH_TOKEN_EXPIRY environment variable.

Request Schema (application/json)
Field NameField TypeRequired
emailstringYes
passwordstringYes
POST/api/customer/tokens
curl
-H "Accept: application/json"
--data-raw "<JSON DATA>"
https://<your domain>/api/customer/tokens
Sample Of Response
{
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImFkbWluX3VzZXJfaWQiOjEsInV1aWQiOiJjNmM4YThmNy1iOWI4LTQzYzYtYWQyNC0zMTdjMzRmY2ZlNzIiLCJzdGF0dXMiOnRydWUsImVtYWlsIjoiYWRtaW5AYWRtaW4uY29tIiwiZnVsbF9uYW1lIjoiYWRtaW4iLCJjcmVhdGVkX2F0IjoiMjAyNC0xMi0xMFQwNzowODoyMS4wMTFaIiwidXBkYXRlZF9hdCI6IjIwMjQtMTItMTBUMDc6MDg6MjEuMDExWiJ9LCJ0b2tlblR5cGUiOiJhZG1pbiIsInRva2VuS2luZCI6ImFjY2VzcyIsImlhdCI6MTc2MjE0NDQyOCwiZXhwIjoxNzYyMTczMjI4LCJhdWQiOiJhZG1pbiIsImlzcyI6ImV2ZXJzaG9wIn0.Dsd1DvAdWOthCv_0fAlHbVmxJNHFzrQvfeMy7p-ozhU",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImFkbWluX3VzZXJfaWQiOjEsInV1aWQiOiJjNmM4YThmNy1iOWI4LTQzYzYtYWQyNC0zMTdjMzRmY2ZlNzIiLCJzdGF0dXMiOnRydWUsImVtYWlsIjoiYWRtaW5AYWRtaW4uY29tIiwiZnVsbF9uYW1lIjoiYWRtaW4iLCJjcmVhdGVkX2F0IjoiMjAyNC0xMi0xMFQwNzowODoyMS4wMTFaIiwidXBkYXRlZF9hdCI6IjIwMjQtMTItMTBUMDc6MDg6MjEuMDExWiJ9LCJ0b2tlblR5cGUiOiJhZG1pbiIsInRva2VuS2luZCI6InJlZnJlc2giLCJpYXQiOjE3NjIxNDQ0MjgsImV4cCI6MTc2MjE0NTMyOCwiYXVkIjoiYWRtaW4iLCJpc3MiOiJldmVyc2hvcCJ9.JF00yEJla1P51JRq8gRUkbnrt080f_GOeh2d8_XGqHU"
}
}

Response Properties

PropertyDescription
accessTokenJWT access token for authenticated requests
refreshTokenJWT refresh token for obtaining new access tokens

Refresh Customer Access Token

Renews the customer access token using a valid refresh token. This endpoint allows you to obtain a new access token without requiring credentials, extending your authenticated session without interruption.

Use Cases:

  • Obtain a new access token after the current one expires
  • Maintain continuous authenticated access without re-entering credentials
  • Implement seamless token rotation in your application

Authentication: Requires valid refresh token

Request Schema (application/json)
Field NameField TypeRequired
refreshTokenstringYes
POST/api/customer/token/refresh
curl
-H "Accept: application/json"
--data-raw "<JSON DATA>"
https://<your domain>/api/customer/token/refresh
Sample Of Response
{
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImFkbWluX3VzZXJfaWQiOjEsInV1aWQiOiJjNmM4YThmNy1iOWI4LTQzYzYtYWQyNC0zMTdjMzRmY2ZlNzIiLCJzdGF0dXMiOnRydWUsImVtYWlsIjoiYWRtaW5AYWRtaW4uY29tIiwiZnVsbF9uYW1lIjoiYWRtaW4iLCJjcmVhdGVkX2F0IjoiMjAyNC0xMi0xMFQwNzowODoyMS4wMTFaIiwidXBkYXRlZF9hdCI6IjIwMjQtMTItMTBUMDc6MDg6MjEuMDExWiJ9LCJ0b2tlblR5cGUiOiJhZG1pbiIsInRva2VuS2luZCI6ImFjY2VzcyIsImlhdCI6MTc2MjE0NDQyOCwiZXhwIjoxNzYyMTczMjI4LCJhdWQiOiJhZG1pbiIsImlzcyI6ImV2ZXJzaG9wIn0.Dsd1DvAdWOthCv_0fAlHbVmxJNHFzrQvfeMy7p-ozhU"
}
}