如何在RTK Query客户端更新NextAuth的session对象?
解决方案
要在RTK Query的baseQuery中更新NextAuth的session,不能直接修改getSession返回的只读对象,而是要用NextAuth提供的updateSession方法来更新客户端session。具体实现如下:
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; import { getSession, updateSession } from "next-auth/react"; const baseQuery = fetchBaseQuery({ baseUrl: "http://localhost:1337/", prepareHeaders: async (headers) => { const session = await getSession(); if (session) { headers.set("Authorization", `Bearer ${session.jwt}`); } return headers; }, }); const baseQueryWithReauth = async (args, api, extraOptions) => { let result = await baseQuery(args, api, extraOptions); if (result.error && (result.error.status === 401 || result.error.status === 403)) { const session = await getSession(); // 调用刷新令牌接口 const refreshResult = await baseQuery( { url: "token/refresh", method: "POST", body: { refreshToken: session?.refreshToken }, }, api, extraOptions ); if (refreshResult.data) { // 构造新的session对象,保留原session的其他属性,替换新的jwt和refreshToken const newSession = { ...session, jwt: refreshResult.data.jwt, refreshToken: refreshResult.data.refreshToken || session.refreshToken, }; // 更新NextAuth的客户端session await updateSession(newSession); // 用新令牌重新发起原请求 result = await baseQuery(args, api, extraOptions); } } return result; }; export const api = createApi({ reducerPath: "api", baseQuery: baseQueryWithReauth, tagTypes: ["Orders"], endpoints: (builder) => ({ getOrders: builder.query({ query: () => ({ url: "api/orders?populate[products][populate][0]=*", }), providesTags: ["Orders"], }), }), });
核心说明
updateSession是NextAuth官方提供的客户端方法,无需依赖组件钩子,可直接在非组件环境(如RTK Query的baseQuery)中调用,专门用于更新客户端存储的session数据- 构造新session时必须展开原session的所有属性,避免丢失用户信息等其他关键session字段
- 重新发起请求时,
prepareHeaders会再次调用getSession,此时拿到的是更新后的session,自动携带新的JWT令牌
内容的提问来源于stack exchange,提问作者BerenBoden
相关产品推荐
相关产品推荐

