Social sign-in should change how a user proves identity, not how the rest of your app handles sessions. JSON API User Plus follows that principle: Apple, Google, and Facebook authenticate through their own SDKs, User Plus verifies the provider credential server-side, and WordPress returns the same Bearer JWT shape used by password login.
That gives your app one post-login path: store token, load user, and attach Authorization: Bearer TOKEN to protected requests.
Shared WordPress settings
Install RESTful JSON API and JSON API User Plus 5.0.4, activate the User Plus license, and open the User Plus settings page. Each provider has its own tab. Two settings apply across SSO:
- Allow SSO registration: when enabled, a valid provider identity can create a WordPress user if no account has that email. When disabled, SSO works only for an existing matching email.
- Default role: the role assigned to a newly created SSO user. Use a least-privilege role such as Subscriber unless the app genuinely needs more.
User Plus links identities by verified email and records provider IDs in user meta. All provider calls return a response containing token, token_type, expires, expires_in, user, and provider.
Apple Sign In
Configure Apple
In the Apple Developer portal, prepare the App ID/Services ID and Sign in with Apple configuration. Your identifiers and redirect URI must match the platform configuration exactly.
In the Apple Connect tab enter:
- Apple Client ID
- Team ID
- Key ID
- Private Key
- Redirect URI
Treat the private key like a production secret. Do not ship it in the app. User Plus uses it on WordPress to create the Apple client secret when exchanging an authorization code.
Web-style authorization-code flow
Request the authorization URL:
GET /api/userplus/apple_request_auth/
The response contains auth_url. Open it in an external user-agent or secure browser session. Apple returns an authorization code to the registered redirect URI. Exchange it on WordPress:
curl -X POST "https://example.com/api/userplus/apple_connect/" \ -d "code=APPLE_AUTHORIZATION_CODE" \ -d "name=Alex Morgan"
Native Apple SDKs may instead provide an identity token:
curl -X POST "https://example.com/api/userplus/apple_connect/" \ -d "id_token=APPLE_ID_TOKEN" \ -d "name=Alex Morgan"
Apple may provide the user’s name only on the first authorization. Capture it immediately and include it when calling apple_connect. Also test Apple’s private-relay email behavior.
Implementation note: v5.0.4 decodes the submitted Apple ID-token payload to obtain
sub; the authorization-code path obtains the token directly from Apple first. For a high-security deployment, review whether your current plugin build performs the level of Apple signature, issuer, audience, nonce, and state verification your threat model requires.
Google Connect
Configure Google
Create OAuth client IDs for each platform in Google Cloud. Android, iOS, web, and development builds may use different client IDs.
In the Google Connect tab, add all accepted client IDs as a comma-separated list. User Plus verifies the token through Google’s token-info service and rejects an audience not in this list. Keeping the list populated is important; an empty allowlist removes that configured audience restriction.
App flow
Use the current Google Sign-In SDK for the target platform and request an ID token intended for your configured server client. Post that ID token—not a Google API access token—to WordPress:
curl -X POST "https://example.com/api/userplus/google_connect/" \ -d "id_token=GOOGLE_ID_TOKEN"
Flutter-style pseudocode:
final googleUser = await googleSignIn.signIn();
final googleAuth = await googleUser!.authentication;
final response = await http.post(
Uri.parse(‘$baseUrl/api/userplus/google_connect/’),
body: {‘id_token’: googleAuth.idToken!},
);
final data = jsonDecode(response.body) as Map<String, dynamic>;
await secureStorage.write(key: ‘jwt’, value: data[‘token’] as String);
The server requires Google to return both an email and stable subject identifier. The email locates an existing WordPress account or creates one when SSO registration is enabled.
Facebook Connect
Configure Meta/Facebook
Create the app, configure Facebook Login for each mobile platform, add the required redirect/deep-link settings, and complete any permissions or review steps required for production email access.
In the Facebook Connect tab enter:
- Facebook App ID
- Facebook App Secret
The secret remains on WordPress. When present, User Plus derives appsecret_proof for the Graph request. Never embed the app secret in a native application.
App flow
Use the Facebook Login SDK to obtain a user access token, then post it to User Plus:
curl -X POST "https://example.com/api/userplus/facebook_connect/" \ -d "access_token=FACEBOOK_USER_ACCESS_TOKEN"
User Plus requests id, name, and email from the Graph API. If Facebook does not return an email, the login fails. Test accounts that have no accessible email and provide a recovery path in your UI.
Normalize all providers in one client method
Your app can reduce every successful response to a single session type:
type UserPlusSession = {
token: string;
token_type: 'Bearer';
expires: number;
expires_in: number;
provider?: 'apple' | 'google' | 'facebook';
user: { id: number; email: string; display_name: string; roles: string[] };
};
async function finishSSO(response: Response): Promise<UserPlusSession> {
const body = await response.json();
if (!response.ok || !body.token) throw new Error(body.error ?? 'SSO_FAILED');
await secureStore.set('userPlusToken', body.token);
return body;
}
After that, call /api/userplus/validate_token/ or /api/userplus/me/ with the Bearer header exactly as you would after password login.
Security and release checklist
- Use the provider’s maintained SDK and system browser flows; never collect provider passwords.
- Validate production bundle IDs, package names, signing certificates, redirect URIs, and client IDs.
- Keep Apple private keys and Facebook app secrets only on the server.
- Use nonce/state and PKCE wherever the provider and client flow support them.
- Configure Google’s allowed client IDs instead of accepting arbitrary audiences.
- Keep SSO registration disabled until your onboarding and role policy are ready.
- Provide account linking/recovery rules for users who previously signed up with a password.
- Test revoked consent, missing email, cancelled login, expired credentials, network failure, and duplicate email accounts.
- Follow Apple and Google account-deletion requirements; User Plus includes a protected
delete_accountendpoint.
Three identity providers now lead to one WordPress session contract. That keeps provider-specific complexity at the edge and lets the rest of the app depend on a stable JWT-authenticated User Plus API.







