Social login
Supported providers
Section titled “Supported providers”Axowl exchanges the provider’s authorization code for the user’s profile on the server. Per provider:
| Provider | client_secret | Notes |
|---|---|---|
| static | id_token validated via Google library | |
| Kakao | static (optional) | userinfo over TLS |
| Naver | static | the service URL in the Naver console is the root domain only |
| LINE | static | id_token verified at LINE /verify |
| GitHub | static | email often private → /user/emails fallback |
| Apple | signed JWT (ES256) | see below — distinct from all others |
Providers are enabled per app group (allowedSocialProviders, toggled at Applications → Login Methods). Provider names in routes and request bodies are case-insensitive. An app group with no provider enabled has social sign-in closed; new app groups start with Google enabled.
Add-on. Kakao and Naver require the Korean Package add-on on the organization. Without it, saving them returns 402 ADDON_REQUIRED, they are dropped from the app’s login-methods list, direct token sign-in returns 402, and the hosted flow returns to the portal with error=provider_disabled. Google, Apple, GitHub and LINE need no add-on.
Apple “Sign in with Apple”
Section titled “Apple “Sign in with Apple””Apple differs from every other provider in exactly one way: client_secret is not a static string but a short-lived ES256 JWT Axowl signs on each token request with the developer .p8 key:
iss= Team ID,sub= Services ID (client_id),aud=https://appleid.apple.com, headerkid= Key ID.- Token endpoint
https://appleid.apple.com/auth/tokenreturns anid_token(JWT) carryingsub+email. Apple sends the user’s name only on first consent (form_post), never in theid_token— Name falls back to the email local-part.
To use your own Apple key you need an Apple Developer Program membership (the Services ID, .p8 key and Return URL registration all require it) — see the next section for where to store it.
Your own OAuth keys per app group
Section titled “Your own OAuth keys per app group”By default an app group signs in with Axowl’s shared OAuth client, so the provider’s consent screen shows Axowl. Store your own client per provider at Applications → Login Methods → Social → Your own OAuth keys, or with PUT /api/org/{slug}/app-groups/{groupId}/social-credentials (reference).
- Create an OAuth client (Google, GitHub, Kakao, Naver), a LINE Login channel, or an Apple Services ID with a
.p8key in the provider’s console. - Register the redirect URI shown on the page (also
redirectUriinGET …/social-credentials) — one callback for all your apps. - Save the key. Fields:
clientId(Apple: Services ID, LINE: Channel ID);clientSecret(LINE: Channel secret; optional for Kakao; not used for Apple); Apple alsoteamId,keyIdandprivateKey(the.p8PEM). Secrets are stored encrypted and never returned.
Once a key is stored, that app group uses only that key: the hosted flow, the callback and direct token sign-in (POST …/auth/social; a Google ID token must be issued to your client ID). Each save raises the key version; a sign-in started before the change returns to the portal with error=credential_changed — start it again. The dashboard’s own sign-in always uses Axowl’s keys.
Promoting an app group to production requires your own key for every enabled provider (Development and production). App groups already in production keep working on the shared keys.
Token mode — org-native — POST /api/auth/login/social
Section titled “Token mode — org-native — POST /api/auth/login/social”The frontend obtains a provider token (e.g. Google idToken) and posts it; Axowl verifies it and issues the session.
Server-mediated — end-user (hosted portal)
Section titled “Server-mediated — end-user (hosted portal)”For end users, Axowl mediates the OAuth round-trip so provider tokens never touch the browser as final credentials:
| Method · Route | Purpose |
|---|---|
GET /api/public/apps/{applicationKey}/auth/social/{provider}/start?redirect_url= | Redirects the browser to the provider. Used by the hosted login page. |
POST /api/public/apps/{applicationKey}/auth/social/exchange | { "code" } → the end-user JWT. The code is the one the portal’s /social-callback receives after the provider round-trip; it is single-use and valid for 2 minutes (401 otherwise). |
POST /api/public/apps/{applicationKey}/auth/social | Direct token sign-in: { "provider", "token" } with a token your own client obtained from the provider. |
In the hosted flow the provider returns to Axowl, Axowl issues a one-time code, and that code is exchanged for the end-user JWT — the token travels in the exchange response, never in a URL. Failures return to the portal as ?error= (bad_provider, provider_disabled, credential_changed, not_public).