Repository navigation
Best practices for Custom OAuth/Social Login & Session Management #16564
Replies: 1 comment
|
You are close — the missing piece is using Payload's built-in Payload v3 exposes Here is a cleaner version of your handler: import type { PayloadHandler } from 'payload'
import { generatePayloadCookie, getCookieExpiration } from 'payload/utilities'
export const oauthLoginHandler: PayloadHandler = async (req) => {
const data = await req.json?.()
const { email, name, provider, externalId } = data
if (process.env.INTERNAL_SECRET_KEY !== req.headers.get('x-internal-secret')) {
return Response.json({ error: 'Unauthorized' }, { status: 401 })
}
const payload = req.payload
const collectionConfig = payload.collections['users'].config
// Find or create the user
let user = await payload
.find({
collection: 'users',
where: { and: [{ provider: { equals: provider } }, { externalId: { equals: externalId } }] },
depth: 0,
})
.then((res) => res.docs[0])
if (!user && email) {
user = await payload.create({
collection: 'users',
data: {
email,
name,
provider,
externalId,
password: crypto.randomBytes(32).toString('hex'),
role: 'user',
_verified: true,
},
})
}
if (!user) {
return Response.json({ error: 'User not found and could not be created' }, { status: 400 })
}
// Use Payload's own JWT signing — same secret and expiry as a normal login
const token = await payload.sign(
{ id: user.id, email: user.email, collection: 'users' },
collectionConfig.auth.tokenExpiration,
)
// Generate the HTTP-only cookie Payload normally sets on login
const cookie = generatePayloadCookie({
collectionAuthConfig: collectionConfig.auth,
cookiePrefix: payload.config.cookiePrefix,
token,
})
return Response.json(
{ user, token },
{
status: 200,
headers: { 'Set-Cookie': cookie },
},
)
}Key points
Security noteThe |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Hi everyone!
I am implementing a custom Social Login (OAuth) flow in Payload CMS 3 that interacts with a Nuxt.js frontend.
My current handler logic is as follows:
Payload-native approach: Is there a way to trigger Payload's internal login logic (which handles session persistence automatically) from within a custom handler, rather than re-implementing jwtSign and manual DB updates?
Here is my current oauthLoginHandler.ts:
All reactions