Skip to content
Orvanov0.2.0

Verify tokens on your server

When your app calls your own backend, it sends the user’s access token in Authorization: Bearer <token>. Your backend checks the token and learns who the user is, usually without calling Orvano. The Dart and .NET quickstarts build exactly this.

const session = await orvano.client.getSession() // refreshed first when needed
await fetch('/api/orders', { headers: { Authorization: `Bearer ${session!.accessToken}` } })
import { Client, OrvanoError } from '@orvano/js/server'
const client = new Client({ endpoint: process.env.ORVANO_ENDPOINT!, project: process.env.ORVANO_PROJECT! })
try {
const token = await client.verifyAccessToken(accessToken)
// token.userId, token.sessionId, token.emailVerified, token.expiresAt
} catch (error) {
if (error instanceof OrvanoError && error.status === 401) return new Response(null, { status: 401 })
throw error
}

The SDK checks that:

  • the token is an ES256 JWT signed by one of the project’s keys, which it fetches from keys.getJwks and keeps for 10 minutes;
  • it was issued for this project (iss is <your Orvano URL>/v1/projects/<projectId>, and aud is the project ID);
  • it hasn’t expired, allowing 30 seconds of clock difference.

A bad token throws a 401 invalid_token, an expired one a 401 token_expired. Answer 401 to both; the client SDKs refresh the session and try again. Checking needs only the project ID, not an API key. The SDK needs an API key only for what comes next, such as loading the user with users.get.

The check above is offline: a token whose session ended (sign out, a password change, a blocked user) still passes until it expires, at most 15 minutes later. For actions where that matters, such as payments or deleting data, pass online: true. The SDK then also asks Orvano whether the session is still active, which costs one call:

const token = await client.verifyAccessToken(accessToken, { online: true })

Any JWT library can check the tokens. Point it at the project’s keys, <your Orvano URL>/v1/projects/<projectId>/.well-known/jwks.json, or at the discovery document from keys.getOpenIdConfiguration. Accept only ES256, and check iss, aud, and exp as above. The claims are sub (the user ID), sid (the session ID), and email_verified.

Orvano rotates a project’s signing key when an owner asks; the old key stays in the key set for 24 hours, so tokens signed with it keep working until they expire. When you see an unknown key ID, fetch the key set again.