Next.js App Router SSR集成Mongo Realm:登录后app.currentUser为null问题
Next.js App Router + Mongo Realm 登录后获取用户信息问题排查与解决
问题描述
使用Next.js App Router结合Mongo Realm实现用户注册登录功能,登录API可正常返回响应并设置Cookie,但调用getUser API获取用户信息时,app.currentUser始终返回null。
登录API代码
import { createSessionToken } from "@/app/lib/authUtils"; import { NextResponse } from "next/server"; import { App, Credentials } from "realm-web"; const app = new App({ id: "app-id" }); export async function POST(req: Request) { try { const { email, password } = await req.json(); if (!email || !password) { return NextResponse.json( { error: "Email and password are required" }, { status: 400 } ); } const credentials = Credentials.emailPassword(email, password); const user = await app.logIn(credentials); if (!user) { return NextResponse.json( { error: "Invalid email or password" }, { status: 401 } ); } const token = createSessionToken({ email: user.profile.email ?? "", name: user.profile.name ?? "", token: user.accessToken ?? "", }); const res = NextResponse.json({ user }); res.cookies.set("session", token, { httpOnly: true, secure: process.env.NODE_ENV === "production", maxAge: 60 * 30, // 30 minutes path: "/", }); return res; } catch (error: any) { return NextResponse.json({ error: error.message }, { status: 500 }); } }
获取用户API代码
import { getSession } from "@/app/lib/authUtils"; import { NextResponse } from "next/server"; import { App } from "realm-web"; const app = new App({ id: "app-id" }); export async function GET(req: Request) { try { const sessionData = await getSession(); if (!sessionData || !sessionData.token) { return NextResponse.json( { error: "No session token found" }, { status: 401 } ); } const user = app.currentUser; const checkSameUser = user?.accessToken === sessionData.token && user; return NextResponse.json({ data: checkSameUser }, { status: 200 }); } catch (error: any) { return NextResponse.json({ error: error.message }, { status: 500 }); } }
疑问解答
1. 登录成功后app.currentUser为何返回null?
Next.js App Router的API路由是无状态的独立请求上下文,每次调用API都会重新实例化App对象。登录API中的app实例和getUser API中的app实例完全是两个独立的对象,getUser里的app从未执行过logIn操作,自然currentUser为null。
2. 当前技术栈能否实现该功能?
完全可以。Next.js App Router + Mongo Realm的组合是成熟的技术方案,只要正确处理会话持久化与用户验证逻辑,就能实现登录后获取用户信息的功能。
3. 如何正确获取登录用户的详情?
推荐两种可行方案:
方案1:直接返回会话中存储的用户基础信息
如果createSessionToken已经将用户的邮箱、姓名等基础信息加密存储在Cookie的session token中,可直接解析后返回,无需再次调用Realm:
export async function GET(req: Request) { try { const sessionData = await getSession(); if (!sessionData || !sessionData.token) { return NextResponse.json( { error: "No session token found" }, { status: 401 } ); } // 直接返回session中存储的用户信息 return NextResponse.json({ data: { email: sessionData.email, name: sessionData.name } }, { status: 200 }); } catch (error: any) { return NextResponse.json({ error: error.message }, { status: 500 }); } }
优点:高效,无需额外Realm请求;缺点:只能返回预存的固定信息,无法获取用户最新状态。
方案2:用Access Token重新验证并获取用户
通过Realm的logIn方法传入已有的access token,验证token有效性并获取完整用户对象:
export async function GET(req: Request) { try { const sessionData = await getSession(); if (!sessionData || !sessionData.token) { return NextResponse.json( { error: "No session token found" }, { status: 401 } ); } // 使用access token重新登录验证,获取用户对象 const user = await app.logIn({ accessToken: sessionData.token }); // 双重验证token一致性 if (user.accessToken !== sessionData.token) { return NextResponse.json({ error: "Invalid session token" }, { status: 401 }); } return NextResponse.json({ data: user }, { status: 200 }); } catch (error: any) { return NextResponse.json({ error: error.message }, { status: 500 }); } }
优点:验证token有效性,能获取用户最新信息;缺点:需要额外调用Realm服务,存在一定网络开销。
内容的提问来源于stack exchange,提问作者Meet Patel
相关产品推荐
相关产品推荐

