Skip to content

Social login

Server-mediated code → profile exchange is centralized in one switch — SocialTokenVerifier.ExchangeCodeAsync — with one private exchange method per provider:

Providerclient_secretNotes
Googlestaticid_token validated via Google library
Kakaostatic (optional)userinfo over TLS
Naverstaticservice-URL = root domain only (axowl.com)
LINEstaticid_token verified at LINE /verify
GitHubstaticemail often private → /user/emails fallback
Applesigned JWT (ES256)see below — distinct from all others

Per-app enablement lives on the App Group (AllowedSocialProviders, toggled at Applications → Login Methods). The provider name maps to the SocialProvider enum via Enum.Parse(..., ignoreCase: true) — no per-provider glue.

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 (SocialTokenVerifier.BuildAppleClientSecret):

  • iss = Team ID, sub = Services ID (client_id), aud = https://appleid.apple.com, header kid = Key ID.
  • Token endpoint https://appleid.apple.com/auth/token returns an id_token (JWT) carrying sub + email. Apple sends the user’s name only on first consent (form_post), never in the id_token — Name falls back to the email local-part.

Required secrets (Secret Manager → /etc/axowl/env):

Authentication:Apple:ClientId = Services ID (e.g. com.axowl.signin)
Authentication:Apple:TeamId = 10-char Apple Team ID
Authentication:Apple:KeyId = 10-char Key ID of the .p8
Authentication:Apple:PrivateKey = .p8 contents (PEM, BEGIN PRIVATE KEY)

Inert until configured: with the secrets unset, the Apple branch throws "Apple client credentials not configured." exactly like Google/GitHub — zero effect on live providers. Requires an Apple Developer Program membership (the Services ID, .p8 key, and Return URL registration are all paid-tier features).

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 (AuthEndpoints.cs:106, LoginWithSocialCommand).

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 · RouteSource
POST /api/public/apps/{applicationKey}/auth/socialPublicEndpoints.cs:156
POST /api/public/apps/{applicationKey}/auth/social/exchange:384

The flow exchanges a provider authorization for a one-time code, then exchanges that code for the end-user JWT (token delivered via the code, not the URL fragment). Provider notes (e.g. Naver service-URL constraints) apply per provider console config.