Authentication
Authentication
Section titled “Authentication”BitMarks uses OAuth 2.0 via WorkOS AuthKit for authentication. This provides secure, industry-standard authentication with support for social logins and enterprise SSO.
Overview
Section titled “Overview”Authentication Flow
Section titled “Authentication Flow”┌─────────┐ ┌─────────────┐ ┌─────────┐ ┌─────────────┐│ User │────▶│ Your App │────▶│ BitMarks│────▶│ WorkOS ││ │ │ │ │ API │ │ AuthKit │└─────────┘ └─────────────┘ └─────────┘ └─────────────┘ │ │ │ │ │ 1. Click Login │ │ │ │────────────────▶│ │ │ │ │ 2. POST /login │ │ │ │────────────────▶│ │ │ │ │ │ │ │ 3. authorizationUrl │ │ │◀────────────────│ │ │ │ │ │ │ 4. Redirect to authorizationUrl │ │ │◀────────────────│ │ │ │ │ │ │ │ 5. Login at WorkOS │ │ │─────────────────────────────────────────────────────▶ │ │ │ │ │ 6. Redirect to callback with code│ │ │◀───────────────────────────────────────────────────── │ │ │ │ │ 7. GET /callback?code=... │ │ │────────────────────────────────────▶ │ │ │ │ 8. Exchange │ │ │ │────────────────▶│ │ │ │ 9. Tokens │ │ │ │◀────────────────│ │ │ │ │ │ 10. Set cookies & redirect │ │ │◀─────────────────────────────────── │Implementation Guide
Section titled “Implementation Guide”-
Initiate Login
Section titled “Initiate Login”Start the OAuth flow by calling the login endpoint:
Terminal window POST /api/v1/auth/loginContent-Type: application/json{"returnTo": "/dashboard" // Optional: where to redirect after login}Response:
{"authorizationUrl": "https://authkit.workos.com/sso/authorize?client_id=..."} -
Redirect to WorkOS
Section titled “Redirect to WorkOS”Redirect the user to the
authorizationUrl. They’ll see the WorkOS login page where they can:- Sign in with email/password
- Use social login (Google, GitHub, etc.)
- Use enterprise SSO (if configured)
-
Handle Callback
Section titled “Handle Callback”After authentication, WorkOS redirects to your callback URL with an authorization code:
GET /api/v1/auth/callback?code=AUTH_CODE&state=/dashboardThe API automatically:
- Exchanges the code for tokens
- Creates the user in the database (if first login)
- Sets session cookies
- Redirects to the
stateURL (yourreturnTovalue)
-
Use Session Cookie
Section titled “Use Session Cookie”All subsequent requests should include the
bitmarks_sessioncookie:Terminal window GET /api/v1/sync/statusCookie: bitmarks_session=YOUR_SESSION_TOKENIn JavaScript with fetch:
fetch('https://app.bitmarks.sh/api/v1/sync/status', {credentials: 'include' // Includes cookies automatically});
Session Management
Section titled “Session Management”Session Cookie
Section titled “Session Cookie”| Cookie | Duration | Purpose |
|---|---|---|
bitmarks_session | 7 days | Access token for API requests |
bitmarks_refresh | 30 days | Refresh token for obtaining new access tokens |
Cookie Properties
Section titled “Cookie Properties”Set-Cookie: bitmarks_session=TOKEN; HttpOnly; Secure; SameSite=Lax; Domain=.bitmarks.sh; Max-Age=604800Check Current Session
Section titled “Check Current Session”Verify if the user is authenticated and get their info:
GET /api/v1/auth/sessionCookie: bitmarks_session=YOUR_TOKEN{ "authenticated": true, "user": { "user_id": "user_01ABC123", "email": "user@example.com", "name": "John Doe", "avatar_url": "https://avatars.example.com/user.png", "email_verified": true }}{ "authenticated": false}HTTP Status: 401
Refresh Token
Section titled “Refresh Token”When the access token expires, use the refresh token to obtain a new one:
POST /api/v1/auth/refreshCookie: bitmarks_refresh=YOUR_REFRESH_TOKENSuccess Response:
{ "success": true}New bitmarks_session cookie is automatically set.
Error Response (401):
{ "error": "No refresh token"}Logout
Section titled “Logout”Clear session cookies and end the session:
POST /api/v1/auth/logoutResponse:
{ "success": true}Both bitmarks_session and bitmarks_refresh cookies are cleared.
Security Considerations
Section titled “Security Considerations”Best Practices
Section titled “Best Practices”- Always use HTTPS - Session cookies are marked
Secureand won’t be sent over HTTP - Handle token expiration - Implement automatic refresh before requests
- Logout on errors - If you receive persistent 401s, clear local state and re-authenticate
- Secure storage - The browser handles cookie storage securely; don’t manually store tokens
Token Refresh Strategy
Section titled “Token Refresh Strategy”async function apiRequest(url, options = {}) { let response = await fetch(url, { ...options, credentials: 'include' });
// If unauthorized, try refreshing the token if (response.status === 401) { const refreshResponse = await fetch('/api/v1/auth/refresh', { method: 'POST', credentials: 'include' });
if (refreshResponse.ok) { // Retry the original request response = await fetch(url, { ...options, credentials: 'include' }); } else { // Refresh failed, redirect to login window.location.href = '/login'; return; } }
return response;}Error Responses
Section titled “Error Responses”| Status | Error | Meaning |
|---|---|---|
401 | Authentication required | No session cookie provided |
401 | Invalid or expired session | Session token is invalid or expired |
401 | No refresh token | Attempting to refresh without a refresh token |
401 | Failed to refresh token | Refresh token is invalid or expired |
500 | Failed to initiate login | Error communicating with WorkOS |
CORS Configuration
Section titled “CORS Configuration”The API allows credentials from configured origins:
- Production:
https://app.bitmarks.sh - Extension: Chrome extension origin
For local development, configure CORS_ORIGIN environment variable.
Next Steps
Section titled “Next Steps”- Quick Start - Make your first authenticated request
- Sync API - Start syncing bookmarks
- Encryption Guide - Set up client-side encryption