Here’s how I implemented getCurrentUser
with Auth0. I used Auth0’s sub
as the User id
, but I wouldn’t recommend that.
// api/src/lib/auth.js
import { AuthenticationError } from '@redwoodjs/api'
import { AuthenticationClient } from 'auth0'
import { db } from './db'
const auth0 = new AuthenticationClient({
domain: process.env.AUTH0_DOMAIN,
clientId: process.env.AUTH0_CLIENT_ID,
})
export const getCurrentUser = async (jwt, accessToken) => {
// try to find the user
let user = await db.user.findOne({
where: {
id: jwt.sub,
},
})
if (!user && accessToken) {
const auth0User = await auth0.getProfile(accessToken)
// otherwise create a new user
user = await db.user.create({
data: {
id: auth0User.sub,
email: auth0User.email,
// you could add more values
},
})
}
return user
}
If you notice, getCurrentUser
in this implementation actually takes two arguments. The new one is accessToken
. accessToken
is required in order to call out to the Auth0 API to get the profile information. Unfortunately, accessToken
is not in context
. How did I get the accessToken
? I’m glad you asked. I dug around in the RedwoodJS source code and I found out that createGraphQLHandler
takes a context
argument.
export const handler = wrapFunction(
createGraphQLHandler({
schema: makeMergedSchema({
schemas,
services: makeServices({ services }),
}),
db,
async context({ event, context }) {
const accessToken = event.headers?.authorization?.split(' ')?.[1]
const jwt = context.currentUser
const currentUser = await getCurrentUser(jwt, accessToken)
return {
...context,
accessToken,
currentUser,
}
},
})
)