Using OAuth providers for authentication and API access
Neon Auth comes with GitHub and Google OAuth providers pre-configured for authentication. When users sign in with these providers, their accounts are automatically connected, allowing you to access their connected accounts and make API calls on their behalf.
Connected accounts
A connected account represents an external OAuth provider account linked to your user. When a user signs in with OAuth, their account is automatically connected to that provider.
You can access a user's connected account using the useConnectedAccount
hook:
'use client';
import { useUser } from '@stackframe/stack';
export default function Page() {
const user = useUser({ or: 'redirect' });
// Redirects to provider authorization if not already connected
const account = user.useConnectedAccount('google', { or: 'redirect' });
return <div>Google account connected</div>;
}
Providing scopes
Most providers have access control in the form of OAuth scopes. These are the permissions that the user will see on the authorization screen (eg. "Your App wants access to your calendar"). For instance, to read Google Drive content, you need the https://www.googleapis.com/auth/drive.readonly
scope:
'use client';
import { useUser } from '@stackframe/stack';
export default function Page() {
const user = useUser({ or: 'redirect' });
// Redirects to the Google authorization page, requesting access to Google Drive
const account = user.useConnectedAccount('google', {
or: 'redirect',
scopes: ['https://www.googleapis.com/auth/drive.readonly'],
});
// Account is always defined because of the redirect
return <div>Google Drive connected</div>;
}
Check your provider's API documentation to find a list of available scopes.
Retrieving the access token
Once connected with an OAuth provider, obtain the access token with the account.getAccessToken()
function. Check your provider's API documentation to understand how you can use this token to authorize the user in requests.
'use client';
import { useEffect, useState } from 'react';
import { useUser } from '@stackframe/stack';
export default function Page() {
const user = useUser({ or: 'redirect' });
const account = user.useConnectedAccount('google', {
or: 'redirect',
scopes: ['https://www.googleapis.com/auth/drive.readonly'],
});
const { accessToken } = account.useAccessToken();
const [response, setResponse] = useState<any>();
useEffect(() => {
fetch('https://www.googleapis.com/drive/v3/files', {
headers: { Authorization: `Bearer ${accessToken}` },
})
.then((res) => res.json())
.then((data) => setResponse(data))
.catch((err) => console.error(err));
}, [accessToken]);
return <div>{response ? JSON.stringify(response) : 'Loading...'}</div>;
}
Account merging strategies
When a user attempts to sign in with an OAuth provider that matches an existing account, Neon Auth uses the following behavior:
- If a user signs in with an OAuth provider that matches an existing account, Neon Auth will link the OAuth identity to the existing account
- The user will be signed into their existing account
- This requires both credentials to be verified for security
note
The available OAuth providers and their scopes are pre-configured in Neon Auth. Currently, Neon Auth does not support adding or modifying OAuth providers.