应用路由器NEXT.js中的NextAuth|会话未定义

p3rjfoxz  于 9个月前  发布在  其他
关注(0)|答案(1)|浏览(91)

我正在使用NextAuth和NEXT.js应用程序路由器进行身份验证。
Jmeter 板组件被 Package 在auth-guard中,它检查用户是否登录。auth-guard的代码如下。

export default function AuthGuard({ children }: Props) {
  const { loading } = useAuthContext();

  return <>{loading ? <SplashScreen /> : 
  <SeshProviders>
  <Container>
    {children}
  </Container>
  </SeshProviders>
  }</>;
}

// ----------------------------------------------------------------------

function Container({ children }: Props) {
  const router = useRouter();

  const { authenticated, method } = useAuthContext();
  const { data: session, status } = useSession();
  
  

  const [checked, setChecked] = useState(false);
  console.log('session from auth-guard', session);
  const check = useCallback(() => {
    if (status !== 'authenticated') {
      const searchParams = new URLSearchParams({
        returnTo: window.location.pathname,
      }).toString();

      const loginPath = loginPaths[method];

      const href = `${loginPath}?${searchParams}`;
      console.log('taking back from auth guard', session);
      router.replace(href);
    } else {
      setChecked(true);
      console.log('auth-guard said authenticated');
    }
  }, [router, status, session]);

  useEffect(() => {
    check();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  if (!checked) {
    return null;
  }

  return <>{children}</>;
}

字符串
我的下一个认证配置:

// nextauth/auth.ts
export const authOptions: NextAuthOptions = {
  // Configure one or more authentication providers
  session: {
    strategy: 'jwt',
    maxAge: 30 * 24 * 60 * 60, // 30 days
  },
  providers: [
    CredentialsProvider({
      name: 'Credentials',
      credentials: {
        email: { label: 'Email', type: 'text', placeholder: 'jsmith' },
        password: { label: 'Password', type: 'password' },
      },
      async authorize(credentials, req) {
        console.log(credentials);
        if (!credentials) return null;
        const email = credentials.email;
        const password = credentials.password;

        const res = await axios.post(endpoints.auth.login, { email, password });
        if (res.status === 200) {
          const { token, user } = res.data;
          user.token = token;
          return user;
        }
        return null;
      },
    }),
  ],
  secret: process.env.NEXAUTH_SECRET,
  callbacks: {
    async redirect({ url, baseUrl }: { url: string; baseUrl: string }) {
      if (!url) return '/dashboard/user';
      return url;
    },
    async jwt({ token, user }: { token: any; user: any }) {
      if (user) {
        token.accessToken = user.token;
      }
      console.log('jwt', token);
      return token;
    },
    async session({ session, token, user }: { session: any; token: any; user: any }) {
      // Send properties to the client, like an access_token and user id from a provider.
      session.accessToken = token.accessToken;
      session.user.id = token.id;
      console.log('session', session);
      return session;
    },
  },
};

export const getServerAuthSession = () => getServerSession(authOptions);


也可以使用app/API/auth/[... nextauth]/route.ts

import { authOptions } from 'src/nextauth/nextauth';


// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const handler = NextAuth(authOptions);
export { handler as GET, handler as POST };


现在,当我登录时,路由器会将我带到 Jmeter 板上一秒钟,然后将我带回login。console's result
你知道我做错了什么吗?(或者我做对了什么)

u59ebvdq

u59ebvdq1#

最好使用中间件来处理受保护的页面。这也将防止页面在会话加载之前加载。
如果你真的必须在客户端执行此操作,你必须检查状态是否不是"loading"useSession钩子向next-auth提供的auth API发出请求,这将加载会话信息。
你的useEffect也应该依赖于check,因为它可以根据你的会话状态而改变。

相关问题