在Auth0与NextJS中实现角色权限控制,解决getSession无用户角色返回问题
解决方案
核心原因是Auth0默认不会将用户角色信息写入ID Token和返回给NextJS的会话数据,你需要手动配置将角色注入会话,具体操作步骤如下:
1. Auth0控制台配置登录钩子,将角色写入ID Token
- 登录Auth0控制台,进入「Actions」→ 「Flows」,选择
Login登录流程 - 点击右侧「Build Custom」创建自定义Action,名称自定义(比如
add-roles-to-token),运行环境选择Node.js 18及以上版本 - 替换Action代码如下:
exports.onExecutePostLogin = async (event, api) => { // 获取当前用户分配的角色列表 const userRoles = event.authorization?.roles || [] // 写入自定义Claim到ID Token,注意命名空间不要用auth0相关域名,避免冲突 api.idToken.setCustomClaim('https://your-app-domain.com/roles', userRoles) }
- 保存并部署该Action,将其拖拽到Login流程的执行链路中,点击「Apply」保存流程配置
2. 配置NextJS Auth0 SDK,将角色写入会话
修改NextJS项目中的Auth0路由文件(通常是pages/api/auth/[...auth0].js),添加afterCallback钩子读取自定义Claim:
import { handleAuth, handleCallback } from '@auth0/nextjs-auth0' const afterCallback = (req, res, session, state) => { // 读取ID Token中的角色信息,写入session的user字段 session.user.roles = session.idToken['https://your-app-domain.com/roles'] return session } export default handleAuth({ async callback(req, res) { try { await handleCallback(req, res, { afterCallback }) } catch (err) { res.status(err.status || 500).end(err.message) } } })
注意自定义Claim的命名空间需要和上一步配置的完全一致
3. 页面权限校验
配置完成后,调用getSession()就能直接拿到user.roles字段,直接做权限判断即可:
服务端渲染页面校验示例(Pages Router)
// pages/admin.js 管理员页面校验 import { getSession } from '@auth0/nextjs-auth0' export async function getServerSideProps(context) { const session = await getSession(context.req, context.res) // 未登录跳转登录页 if (!session) { return { redirect: { destination: '/api/auth/login', permanent: false } } } // 非管理员跳转403页 if (!session.user.roles.includes('admin')) { return { redirect: { destination: '/403', permanent: false } } } return { props: {} } } export default function AdminPage() { return <div>管理员专属内容</div> }
App Router用法
如果使用App Router,在服务端组件中调用getSession()即可获取到角色字段,判断逻辑和上面完全一致。
排查提示
如果仍然拿不到角色,先确认以下几点:
- 测试用户已经在Auth0控制台的用户管理页面分配了对应的角色
- 重新登录账号,老的会话不会更新角色信息
- 两次配置的自定义Claim命名空间完全一致,没有拼写错误
内容的提问来源于stack exchange,提问作者tcetin
相关产品推荐
相关产品推荐

