OAuth Login
WollyCMS supports OAuth 2.0 login with multiple providers. Users can click a provider button on the admin login page to authenticate. OAuth login skips two-factor authentication — the identity provider has already verified the user.
Supported providers
Section titled “Supported providers”| Provider | Env var prefix | Scope |
|---|---|---|
GOOGLE_ | openid email profile | |
| GitHub | GITHUB_ | read:user user:email |
| Microsoft | MICROSOFT_ | openid email profile User.Read |
Each provider is independent — configure one, two, or all three. The login page automatically shows buttons only for configured providers.
How it works
Section titled “How it works”- User clicks a provider button on the login page
- Browser redirects to the provider’s consent screen
- User approves access (email and profile)
- Provider redirects back to WollyCMS with an authorization code
- WollyCMS exchanges the code for user info (email, name)
- If the email matches an existing CMS user, the account is linked and a session is issued
- If no match and auto-create is enabled, a new editor account is created
- If no match and auto-create is off, the user sees an error
Each provider requires three environment variables plus an optional auto-create flag.
Environment variables
Section titled “Environment variables”| Variable | Required | Description |
|---|---|---|
{PROVIDER}_CLIENT_ID | Yes | OAuth client ID |
{PROVIDER}_CLIENT_SECRET | Yes | OAuth client secret |
{PROVIDER}_REDIRECT_URI | Yes | Callback URL (see below) |
{PROVIDER}_AUTO_CREATE | No | Set to true to auto-create accounts. Default: false |
The redirect URI for each provider follows this pattern:
https://YOUR_CMS_DOMAIN/api/admin/auth/oauth/{provider}/callbackFor example:
https://cms.example.com/api/admin/auth/oauth/google/callbackhttps://cms.example.com/api/admin/auth/oauth/github/callbackhttps://cms.example.com/api/admin/auth/oauth/microsoft/callback
- Go to Google Cloud Console
- Create a project or select an existing one
- Go to APIs & Services → OAuth consent screen
- Choose External (or Internal for Google Workspace orgs)
- Scopes:
email,profile,openid
- Go to APIs & Services → Credentials
- Click Create Credentials → OAuth client ID
- Application type: Web application
- Authorized redirect URI:
https://YOUR_CMS_DOMAIN/api/admin/auth/oauth/google/callback
- Copy the Client ID and Client Secret
GitHub
Section titled “GitHub”- Go to GitHub Developer Settings
- Click New OAuth App
- Application name: your site name
- Homepage URL: your CMS domain
- Authorization callback URL:
https://YOUR_CMS_DOMAIN/api/admin/auth/oauth/github/callback
- Copy the Client ID
- Generate a Client Secret and copy it
Microsoft
Section titled “Microsoft”- Go to Azure App Registrations
- Click New registration
- Name: your site name
- Supported account types: choose based on your needs (single tenant, multi-tenant, or personal accounts)
- Redirect URI: Web →
https://YOUR_CMS_DOMAIN/api/admin/auth/oauth/microsoft/callback
- Copy the Application (client) ID
- Go to Certificates & secrets → New client secret and copy the value
Auto-create mode
Section titled “Auto-create mode”By default, {PROVIDER}_AUTO_CREATE is false. Only existing CMS users can sign in with OAuth — the provider email must match an existing CMS user’s email.
Set {PROVIDER}_AUTO_CREATE=true to allow any user who authenticates with the provider to get an editor account created automatically.
For organizations, the recommended approach is:
- Keep auto-create off (default)
- Pre-create users in System → Users with their provider email
- Users click the provider button — accounts link automatically on first login
Managing connected accounts
Section titled “Managing connected accounts”Users can manage their OAuth connections from System → Account:
- Connected Accounts section shows all linked provider accounts
- Disconnect removes the link (blocked if it’s the user’s only login method)
- Connect buttons appear for configured providers that aren’t yet linked
Adding custom providers
Section titled “Adding custom providers”WollyCMS uses a generic OAuth2 provider interface. To add a new provider:
- Define a provider config in
packages/server/src/auth/oauth.ts:
export const myProvider: OAuthProvider = { name: 'myprovider', authUrl: 'https://auth.example.com/authorize', tokenUrl: 'https://auth.example.com/token', userInfoUrl: 'https://api.example.com/userinfo', scope: 'openid email profile', clientId: () => env.MYPROVIDER_CLIENT_ID, clientSecret: () => env.MYPROVIDER_CLIENT_SECRET, redirectUri: () => env.MYPROVIDER_REDIRECT_URI, autoCreate: () => env.MYPROVIDER_AUTO_CREATE, parseUserInfo: (data) => ({ id: String(data.sub), email: String(data.email), name: String(data.name), emailVerified: !!data.email_verified, }),};- Add it to the
providersmap in the same file - Add the env vars to
src/env.ts - The routes and UI are generic — they’ll pick up the new provider automatically
Security details
Section titled “Security details”- CSRF protection: A random 256-bit state token is signed as a JWT and stored in an HttpOnly cookie (5-minute expiry). The callback verifies the state matches.
- 2FA is skipped: OAuth login bypasses TOTP verification because the provider has already authenticated the user.
- No external dependencies: The OAuth flow uses only the Web Crypto API and
fetch. - Token delivery: The session JWT is passed via URL fragment (
#oauth_token=...), which is never sent to the server. - Email verification: Only provider accounts with verified emails are accepted.
- GitHub special handling: If the GitHub profile doesn’t include an email, WollyCMS fetches from the
/user/emailsendpoint to find the primary verified email.
API endpoints
Section titled “API endpoints”OAuth flow (public)
Section titled “OAuth flow (public)”| Endpoint | Method | Description |
|---|---|---|
/api/admin/auth/oauth/providers | GET | Returns which providers are configured |
/api/admin/auth/oauth/:provider | GET | Redirects to provider consent screen |
/api/admin/auth/oauth/:provider/callback | GET | Handles provider callback, issues session |
Connection management (authenticated)
Section titled “Connection management (authenticated)”| Endpoint | Method | Description |
|---|---|---|
/api/admin/auth/oauth/connections | GET | List connected OAuth accounts |
/api/admin/auth/oauth/connections/:id | DELETE | Disconnect an OAuth account |