OAuth / Social Login
Add Google, GitHub, Apple, Microsoft, Discord, and 4 more OAuth providers to HelloJohn. Setup instructions, callback URLs, and SDK integration for all 9 providers.
HelloJohn supports 9 OAuth providers out of the box. Users can sign in with any enabled provider, and their account is automatically linked or created.
Supported providers
| Provider | Environment Variables | OAuth App URL |
|---|---|---|
HELLOJOHN_GOOGLE_CLIENT_ID/SECRET | console.cloud.google.com | |
| GitHub | HELLOJOHN_GITHUB_CLIENT_ID/SECRET | github.com/settings/developers |
| Apple | HELLOJOHN_APPLE_CLIENT_ID/KEY_ID/TEAM_ID/PRIVATE_KEY | developer.apple.com |
| Microsoft | HELLOJOHN_MICROSOFT_CLIENT_ID/SECRET/TENANT_ID | portal.azure.com |
| Discord | HELLOJOHN_DISCORD_CLIENT_ID/SECRET | discord.com/developers |
| Twitter/X | HELLOJOHN_TWITTER_CLIENT_ID/SECRET | developer.twitter.com |
HELLOJOHN_FACEBOOK_CLIENT_ID/SECRET | developers.facebook.com | |
HELLOJOHN_LINKEDIN_CLIENT_ID/SECRET | linkedin.com/developers | |
| Slack | HELLOJOHN_SLACK_CLIENT_ID/SECRET | api.slack.com/apps |
Configure a provider
1. Create an OAuth app
Create an OAuth app at your provider's developer console. Set the callback URL to:
https://your-hellojohn-instance.com/v1/oauth/callback/{provider}Examples:
https://auth.yourdomain.com/v1/oauth/callback/google
https://auth.yourdomain.com/v1/oauth/callback/github
https://auth.yourdomain.com/v1/oauth/callback/apple2. Set environment variables
# Google
HELLOJOHN_GOOGLE_CLIENT_ID=123456789-abc.apps.googleusercontent.com
HELLOJOHN_GOOGLE_CLIENT_SECRET=GOCSPX-XXXXXXXXXXXXXXXX
# GitHub
HELLOJOHN_GITHUB_CLIENT_ID=Iv1.XXXXXXXXXXXXXXXX
HELLOJOHN_GITHUB_CLIENT_SECRET=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
# Apple (more complex — see Apple section below)
HELLOJOHN_APPLE_CLIENT_ID=com.yourdomain.app
HELLOJOHN_APPLE_TEAM_ID=XXXXXXXXXX
HELLOJOHN_APPLE_KEY_ID=XXXXXXXXXX
HELLOJOHN_APPLE_PRIVATE_KEY_PATH=/secrets/AuthKey_XXXXXXXXXX.p83. Add the sign-in button
import { useAuth } from '@hellojohn/react'
function SocialSignIn() {
const { signInWithOAuth } = useAuth()
return (
<div>
<button onClick={() => signInWithOAuth({ provider: 'google' })}>
Continue with Google
</button>
<button onClick={() => signInWithOAuth({ provider: 'github' })}>
Continue with GitHub
</button>
<button onClick={() => signInWithOAuth({ provider: 'apple' })}>
Continue with Apple
</button>
</div>
)
}import { useAuth } from '@hellojohn/vue'
const { signInWithOAuth } = useAuth()
// In your template:
// <button @click="signInWithOAuth({ provider: 'google' })">Continue with Google</button>import { hellojohn } from './hellojohn'
await hellojohn.auth.signInWithOAuth({
provider: 'google',
redirectUrl: '/dashboard',
})The SDK handles the OAuth redirect flow automatically. After the user authorizes your app, they're redirected back and the session is established.
Account linking
When a user signs in with OAuth using an email that already exists from a previous sign-up, HelloJohn automatically links the OAuth account to the existing user.
You can configure this behavior:
# Behavior when OAuth email matches existing account:
# "link" (default) — link the OAuth provider to existing account
# "require_password" — require the user to confirm with their existing password
# "reject" — block OAuth login if email already exists via email/password
HELLOJOHN_OAUTH_ACCOUNT_LINK_STRATEGY=linkApple Sign-In (special setup)
Apple Sign-In requires a .p8 private key file instead of a client secret:
HELLOJOHN_APPLE_CLIENT_ID=com.yourdomain.app
HELLOJOHN_APPLE_TEAM_ID=XXXXXXXXXX # 10-char Team ID from Apple Developer
HELLOJOHN_APPLE_KEY_ID=XXXXXXXXXX # Key ID from your Sign in with Apple key
HELLOJOHN_APPLE_PRIVATE_KEY_PATH=/secrets/AuthKey_XXXXXXXXXX.p8Apple requires https:// redirect URLs. You cannot use http://localhost in production. For local development, use a tunneling service like ngrok.
Using pre-built UI components
Each SDK provides pre-built OAuth buttons:
import { OAuthButton } from '@hellojohn/react'
// Single button
<OAuthButton provider="google" />
// All enabled providers
import { OAuthButtons } from '@hellojohn/react'
<OAuthButtons /><template>
<OAuthButton provider="google" />
<!-- or all enabled providers: -->
<OAuthButtons />
</template>
<script setup>
import { OAuthButton, OAuthButtons } from '@hellojohn/vue'
</script>Accessing the OAuth access token
The OAuth provider's access token is stored (encrypted) and available for making provider-specific API calls:
import { useUser } from '@hellojohn/react'
const { user } = useUser()
// Get connected OAuth providers
console.log(user.oauthProviders)
// [{ provider: 'google', connected: true }, ...]To get the raw OAuth access token on the server (for e.g. reading Google Calendar):
GET /v1/users/me/oauth-tokens/{provider}
Authorization: Bearer {user_access_token}
# Response
{
"provider": "google",
"access_token": "ya29.XXXXXXX",
"expires_at": "2026-01-15T11:00:00Z"
}Common errors
| Error | Cause | Solution |
|---|---|---|
oauth_provider_not_configured | Provider env vars not set | Add the provider credentials to .env |
oauth_callback_url_mismatch | Callback URL in OAuth app doesn't match | Update the callback URL in the provider's developer console |
oauth_state_mismatch | CSRF protection triggered | Usually caused by cross-tab issues; ask user to retry |
oauth_email_required | Provider didn't return an email | Some providers require explicit scope; add email scope |
Next steps
Email + Password
Configure email and password authentication in HelloJohn — registration flow, password policy, login, password reset, and email verification.
Magic Links
Enable passwordless authentication via email magic links in HelloJohn. Setup, SMTP configuration, customization, and SDK integration.