Security
CORS Configuration
Allowed origin rules, browser behavior, and safe expectations for cross-origin SSO consumers.
5.29.0
Overview
Cross-Origin Resource Sharing (CORS) allows your application to make secure requests to the SSO service from a different origin (domain). This is essential for OAuth 2.0 flows and API interactions.
Important
Your application's origin must be registered with the SSO admin before CORS requests will be allowed.
SSO CORS Policy
The SSO service implements the following CORS policy:
- ✅ Allowed Origins: Only pre-registered origins (no wildcards)
- ✅ Credentials: Cookies are allowed (
Access-Control-Allow-Credentials: true) - ✅ Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
- ✅ Headers: Content-Type, Authorization, X-Requested-With
- ⚠️ Preflight Caching: 24 hours (
Access-Control-Max-Age: 86400)
Registering Your Origin
To enable CORS for your application, contact the SSO administrator to register your origin(s):
- Determine your application's origin(s) (e.g.,
https://myapp.com) - Contact SSO admin via email:
sso@doneisbetter.com - Provide the following information:
- Your application name
- Origin URL(s) (must be HTTPS in production)
- OAuth
client_id(if already issued) - Redirect URI(s) for OAuth callback
- Wait for admin approval (typically within 24 hours)
Local development note
For local development, http://localhost origins (any port) are automatically allowed.
CORS Headers in SSO Responses
When your origin is registered, the SSO service will include these headers in responses:
// Example SSO Response Headers
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://myapp.com
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With
Access-Control-Max-Age: 86400
Vary: Origin
// If origin is NOT registered:
HTTP/1.1 403 Forbidden
{ "error": "Origin not allowed" }Client-Side CORS Configuration
Fetch API (Recommended)
// WHY: Include credentials (cookies) in cross-origin requests
const response = await fetch('https://sso.doneisbetter.com/api/public/session', {
method: 'GET',
credentials: 'include', // REQUIRED: Sends HTTP-only cookies
headers: {
'Content-Type': 'application/json'
}
});
const data = await response.json();Axios
import axios from 'axios';
// Global configuration
axios.defaults.withCredentials = true;
// Per-request configuration
const response = await axios.get(
'https://sso.doneisbetter.com/api/public/session',
{ withCredentials: true }
);XMLHttpRequest (Legacy)
const xhr = new XMLHttpRequest();
xhr.withCredentials = true; // REQUIRED for cookies
xhr.open('GET', 'https://sso.doneisbetter.com/api/public/session');
xhr.send();Backend CORS Configuration (Your App)
If your backend needs to call SSO APIs, no CORS configuration is needed—server-to-server requests bypass CORS entirely.
However, if your frontend calls your backend, which then calls SSO, configure CORS on your backend:
Express.js
const cors = require('cors');
app.use(cors({
origin: 'https://yourfrontend.com', // Your frontend origin
credentials: true // Allow cookies
}));Next.js API Routes
// pages/api/auth/[...].js
export default function handler(req, res) {
res.setHeader('Access-Control-Allow-Origin', 'https://yourfrontend.com');
res.setHeader('Access-Control-Allow-Credentials', 'true');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
if (req.method === 'OPTIONS') {
return res.status(200).end();
}
// Handle actual request
}Common CORS Errors
Error: "Origin not allowed"
Cause: Your origin is not registered with the SSO service.
Solution: Contact SSO admin to register your origin.
Error: "Credentials flag not set"
Cause: You're not sending credentials: 'include' in requests.
Solution: Add credentials: 'include' to fetch calls or withCredentials: true to Axios.
Error: "Preflight request failed"
Cause: OPTIONS preflight request is being blocked.
Solution: Ensure your origin is registered and you're using HTTPS (not HTTP) in production.
Testing CORS Configuration
// Test if your origin is allowed
fetch('https://sso.doneisbetter.com/api/health', {
method: 'GET',
credentials: 'include'
})
.then(response => {
console.log('CORS OK:', response.ok);
console.log('Headers:', response.headers.get('Access-Control-Allow-Origin'));
})
.catch(error => {
console.error('CORS Error:', error);
});Summary
- ☑️ Contact SSO admin to register your origin
- ☑️ Always use
credentials: 'include'for API requests - ☑️ Use HTTPS in production (HTTP only for localhost development)
- ☑️ Test CORS configuration before going live