You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextJS中next-auth v4+CognitoProvider角色认证:角色未传入Session

问题描述

使用NextAuth v4的CognitoProvider实现基于角色的认证,已自定义Provider添加角色字段,但返回的session JSON中未包含该角色属性。相关代码如下:

import NextAuth from "next-auth/next";

function CognitoProvider(options) {
  return {
    id: "cognito",
    name: "Cognito",
    type: "oauth",
    wellKnown: `${options.issuer}/.well-known/openid-configuration`,
    idToken: true,
    profile(profile) {
      console.log(profile);
      return {
        id: profile.sub,
        name: profile.name,
        email: profile.email,
        image: profile.picture,
        role: profile["cognito:groups"],
      };
    },
    options,
  };
}

export default NextAuth({
  providers: [
    CognitoProvider({
      clientId: process.env.COGNITO_CLIENT_ID,
      clientSecret: process.env.COGNITO_CLIENT_SECRET,
      issuer: process.env.COGNITO_DOAMIN,
    }),
  ],
  callbacks: {
    session: (props) => {
      console.log(props);
      return props.session;
    },
  },
});

profile对象控制台日志:
profile对象日志

实际session对象(无role属性):
实际session对象

已将用户添加至admin组,需实现让该用户访问NextJS应用特定路由的功能,求解决方案。


解决方案

问题核心是session回调未将用户的role属性同步到session对象。NextAuth的session默认仅包含基础用户信息,需手动从user/token中取出role并添加到session里。

修改代码如下:

import NextAuth from "next-auth/next";

function CognitoProvider(options) {
  return {
    id: "cognito",
    name: "Cognito",
    type: "oauth",
    wellKnown: `${options.issuer}/.well-known/openid-configuration`,
    idToken: true,
    profile(profile) {
      console.log(profile);
      return {
        id: profile.sub,
        name: profile.name,
        email: profile.email,
        image: profile.picture,
        role: profile["cognito:groups"],
      };
    },
    options,
  };
}

export default NextAuth({
  providers: [
    CognitoProvider({
      clientId: process.env.COGNITO_CLIENT_ID,
      clientSecret: process.env.COGNITO_CLIENT_SECRET,
      issuer: process.env.COGNITO_DOAMIN,
    }),
  ],
  callbacks: {
    // 首次登录时将role存入JWT token
    jwt: ({ token, user }) => {
      if (user) {
        token.role = user.role;
      }
      return token;
    },
    // 将token中的role同步到session对象
    session: ({ session, token }) => {
      if (session.user) {
        session.user.role = token.role;
      }
      return session;
    },
  },
});

关键说明

  1. profile函数返回的user对象仅在首次登录时传递给jwt回调,这里把role存入token,确保后续请求能持续获取到该字段
  2. session回调负责将token中的role同步到前端可见的session.user中,这样前端或服务端都能拿到role属性做权限判断

路由权限验证示例

在需要保护的路由(如pages/admin.js)中,可通过getServerSideProps验证角色:

import { getSession } from "next-auth/react";

export async function getServerSideProps(context) {
  const session = await getSession(context);
  
  // 无session或非admin用户直接跳转登录页
  if (!session || !session.user.role?.includes('admin')) {
    return {
      redirect: {
        destination: '/login',
        permanent: false,
      },
    };
  }
  
  return { props: {} };
}

内容的提问来源于stack exchange,提问作者Arihant Jain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 05:35:22