Sign in with Beezifi

OAuth 2.0 & OpenID Connect developer documentation — integrate Beezifi authentication into any application.

On this page

Overview Endpoints Register App Auth Flow Token Exchange User Info Sign Out ID Token Verification Error Handling Security Checklist

Overview

Beezifi Identity supports the OAuth 2.0 Authorization Code flow with OpenID Connect. Your application redirects users to Beezifi for authentication, receives a short-lived authorization code, and exchanges it for tokens.

  • Response type: code
  • Client auth: client_secret_post
  • Scopes: openid profile email
  • ID token signing: RS256 (verified via JWKS)

To get started, create a Beezifi account and register your application under My Apps.

Endpoints

GET /.well-known/openid-configuration
GET /.well-known/jwks.json
GET /api/oauth/authorize
POST /api/oauth/consent
POST /api/oauth/token
GET /api/oauth/userinfo
POST /api/oauth/logout
Base URL:
All endpoints are relative to this base URL, which is the configured identity server address.

Register Your Application

  1. Create a Beezifi account or sign in.
  2. Open My Apps from the dashboard.
  3. Click Register app and fill in the app name and description.
  4. Add one or more redirect URIs (one per line).
  5. Save — copy your client_id and client_secret.

Redirect URI matching is strict — scheme, host, port, path, and trailing slash must all match exactly. Wildcards are not supported.

Authorization Request

Redirect your user to Beezifi to begin authentication:

GET {{BASE_URL}}/api/oauth/authorize
  ?client_id=YOUR_CLIENT_ID
  &redirect_uri=https://yourapp.com/auth/callback
  &response_type=code
  &scope=openid%20profile%20email
  &state=RANDOM_CSRF_VALUE
  &nonce=RANDOM_NONCE

If the user authenticates and grants consent, they are redirected to your redirect_uri with ?code=AUTH_CODE&state=YOUR_STATE. Always verify the state value matches what you sent.

Token Exchange

Exchange the authorization code for tokens from your backend:

POST {{BASE_URL}}/api/oauth/token
Content-Type: application/json

{
  "grant_type": "authorization_code",
  "code": "AUTH_CODE",
  "redirect_uri": "https://yourapp.com/auth/callback",
  "client_id": "YOUR_CLIENT_ID",
  "client_secret": "YOUR_CLIENT_SECRET"
}

Successful response:

{
  "access_token": "eyJ...",
  "id_token": "eyJ...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "openid profile email"
}
Never perform the token exchange from a browser — always from a backend server where your client_secret is protected.

User Info

Fetch the authenticated user's profile using the access token:

GET {{BASE_URL}}/api/oauth/userinfo
Authorization: Bearer ACCESS_TOKEN

Response:

{
  "sub": "user-uuid",
  "email": "user@example.com",
  "name": "Jane Doe",
  "picture": null,
  "email_verified": true
}

Sign Out (RP-Initiated Logout)

When a user signs out of your third-party app, call Beezifi logout to end the account session at the identity provider. This revokes active access tokens and deactivates active Beezifi sessions for that account.

POST {{BASE_URL}}/api/oauth/logout
Authorization: Bearer ACCESS_TOKEN

Successful response:

{
  "message": "Logged out successfully."
}
Also clear your app's local session after calling this endpoint. Any revoked Beezifi access token will fail on subsequent API calls.

ID Token Verification

ID tokens are signed with RS256 (asymmetric RSA). Your backend verifies them using Beezifi's public key — no shared secret required. Fetch the public key from the JWKS endpoint:

GET {{BASE_URL}}/.well-known/jwks.json

Response:

{
  "keys": [
    {
      "kty": "RSA",
      "use": "sig",
      "alg": "RS256",
      "kid": "beezifi-1",
      "n": "...",
      "e": "AQAB"
    }
  ]
}

Match the token's kid header claim to the correct key in the JWKS array, then verify the signature. Most JWT libraries support JWKS natively:

// Node.js example using jose
import { createRemoteJWKSet, jwtVerify } from 'jose';

const JWKS = createRemoteJWKSet(
  new URL('{{BASE_URL}}/.well-known/jwks.json')
);

const { payload } = await jwtVerify(idToken, JWKS, {
  issuer:   '{{BASE_URL}}',
  audience: 'YOUR_CLIENT_ID',
  algorithms: ['RS256'],
});

console.log(payload.sub);   // user UUID
console.log(payload.email); // user email

After verifying the signature, always validate these claims:

  • iss — must equal the Beezifi Identity base URL
  • aud — must equal your client_id
  • exp — must be in the future
  • nonce — must match the value you sent in the authorization request
Cache the JWKS response and only re-fetch when you encounter an unknown kid. Keys rotate infrequently but the endpoint is always authoritative.

Error Handling

Authorization errors are returned as query parameters on the redirect URI:

  • access_denied — user denied consent or an access policy blocked sign-in.
  • invalid_client — bad client credentials or inactive application.
  • invalid_grant — expired, already-used, or mismatched authorization code / redirect URI.
  • invalid_request — missing or malformed required parameters.
  • invalid_token — access token is invalid, expired, or revoked (for example after logout).

Token endpoint errors are returned as JSON with an error field.

Security Checklist

  • Generate a cryptographically random state value and verify it exactly on callback to prevent CSRF.
  • Generate a cryptographically random nonce and validate it in the ID token.
  • Store client_secret only in backend environment variables — never in client-side code.
  • Use HTTPS for all redirect URIs in production.
  • Verify the ID token signature using the public key from /.well-known/jwks.json — never skip signature verification.
  • Validate ID token claims: issuer (iss), audience (aud), expiration (exp), and nonce.
  • Match the token's kid to the correct key in the JWKS response.
  • Reject replayed or already-used authorization codes.
  • Set appropriate token storage — avoid localStorage for sensitive tokens; prefer HttpOnly cookies.
For full integration reference also see docs/sign-in-with-beezifi.md in the repository.