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

Next.js & RTK Query:无需getInitialProps实现全局页面用户校验

实现方案:Next.js + RTK Query + NextAuth 登录状态校验与动态布局

核心思路

避开getInitialProps的性能问题,也不在_app.tsx硬套服务端逻辑,而是通过NextAuth的客户端API获取登录状态,结合RTK Query的状态管理能力,在客户端层面实现动态布局切换;同时可以搭配NextAuth的服务端中间件做路由保护,兼顾体验和安全。

具体步骤

1. 先搭好NextAuth基础环境

先把认证流程跑通,不用先纠结RTK:

  • 安装依赖:npm install next-auth
  • 在pages/api/auth/[...nextauth].ts里配置你的认证提供商(比如账号密码、第三方登录),确保能正常返回用户会话信息
  • 用NextAuth的useSession钩子在任意组件里测试,确认能拿到session对象(包含用户ID、昵称等信息)

2. RTK Query与登录状态联动

RTK Query主要用来拉取用户业务数据(比如个人信息、权限),和NextAuth的会话状态绑定:

  • 在RTK Query的API切片里,把NextAuth返回的用户唯一标识(比如session?.user?.id)作为请求参数,示例:
    import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
    
    export const userApi = createApi({
      reducerPath: 'userApi',
      baseQuery: fetchBaseQuery({ baseUrl: '/api/' }),
      endpoints: (builder) => ({
        getUserProfile: builder.query({
          query: (userId) => `users/${userId}`,
        }),
      }),
    });
    
    export const { useGetUserProfileQuery } = userApi;
    
  • 在需要用户数据的组件里,先拿会话状态再触发请求,没登录就跳过:
    import { useSession } from 'next-auth/react';
    import { useGetUserProfileQuery } from '@/features/api/userApi';
    
    const Profile = () => {
      const { data: session } = useSession();
      const { data: userProfile } = useGetUserProfileQuery(session?.user?.id || '', {
        skip: !session,
      });
    
      // 根据userProfile渲染内容
    };
    

3. 在_app.tsx实现动态头部

直接在_app.tsx里用useSession判断登录状态,切换头部组件:

import { SessionProvider } from 'next-auth/react';
import { AppProps } from 'next/app';
import { Provider } from 'react-redux';
import { store } from '@/app/store';
import LoggedInHeader from '@/components/LoggedInHeader';
import GuestHeader from '@/components/GuestHeader';

export default function MyApp({ Component, pageProps: { session, ...pageProps } }: AppProps) {
  return (
    <SessionProvider session={session}>
      <Provider store={store}>
        {/* 根据会话状态切换头部 */}
        {session ? <LoggedInHeader /> : <GuestHeader />}
        <Component {...pageProps} />
      </Provider>
    </SessionProvider>
  );
}

注意:SessionProvider必须包在最外层,确保所有子组件都能获取会话状态;RTK的Provider也要放在正确层级。

4. 路由保护(可选但推荐)

如果需要某些页面必须登录才能访问,用NextAuth的middleware.ts(Next.js 12+支持)做服务端拦截,不用在每个页面写getServerSideProps:

// middleware.ts
import { withAuth } from 'next-auth/middleware';

export default withAuth({
  callbacks: {
    authorized({ req, token }) {
      // 简单判断:有token就是已登录
      return !!token;
    },
  },
});

// 指定需要保护的路由
export const config = {
  matcher: ['/dashboard/:path*', '/profile'],
};

5. 优化:自动携带认证令牌

在RTK Query的baseQuery里自动注入NextAuth的令牌,不用每个请求手动加:

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

const baseQuery = fetchBaseQuery({
  baseUrl: '/api/',
  prepareHeaders: async (headers) => {
    const session = await getSession();
    if (session?.user?.token) {
      headers.set('authorization', `Bearer ${session.user.token}`);
    }
    return headers;
  },
});

注意细节

  • _app.tsx里确实不能用getServerSideProps,完全依赖客户端的useSession就足够处理布局切换,首次加载时可以加个加载态避免闪烁:
    const { data: session, status } = useSession();
    if (status === 'loading') return <LoadingSpinner />;
    
  • 如果某些页面需要服务端渲染用户状态(比如SEO需求),可以在具体页面用getServerSideProps调用NextAuth的getServerSession,把session传给页面组件,但_app.tsx依然用客户端逻辑处理布局

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 04:50:45