SvelteKit中如何将数据从endpoint传递到getSession()?
问题原因说明
1. 为什么resolve(request)执行前拿不到request.locals.user
SvelteKit的handle钩子执行逻辑是固定顺序的:
- 请求进入后最先触发
handle钩子,你此时从Cookie中读取了accessToken、refreshToken赋值给locals,但还没有执行路由对应的业务逻辑,所以user字段自然为空 - 当你调用
await resolve(request)时,SvelteKit才会开始匹配路由,执行你写的登录接口post逻辑,你在接口中对req.locals的所有修改,都是作用在当前请求的同一个locals对象上的 - 等
resolve执行完成,代表路由对应的业务逻辑已经跑完,你再读取locals自然就能拿到接口中赋值的user字段
2. 为什么endpoint里给locals赋值后getSession拿不到
你当前的场景是登录成功后返回302重定向,这里的核心误区是:你在登录POST请求里修改的locals,只存在于当前POST请求的上下文,和重定向后浏览器发起的新GET请求是完全独立的两个请求。
重定向后的新请求会重新走一遍handle钩子逻辑,你目前的handle里只从Cookie读取了accessToken、refreshToken,没有读取用户信息,所以新请求的locals里没有user,getSession自然拿不到对应值。
解决方案
不需要强制在handle里执行getUser,两种常用方案可选:
方案1:把用户信息存入加密Cookie
登录成功时把用户信息序列化后写入加密的HttpOnly Cookie,然后在handle钩子中直接从Cookie读取用户信息赋值给locals即可,不用每次都调用接口拉取用户。
方案2:在handle中统一拉取用户信息
如果不想把用户信息存在Cookie,可以在handle钩子中判断当前请求的locals有accessToken时,就调用getUser拉取用户信息赋值给locals,可以配合内存缓存避免每次请求都调用接口:
export async function handle({request, resolve}) { const cookies = cookie.parse(request.headers.cookie || '') request.locals.accessToken = cookies.accessToken request.locals.refreshToken = cookies.refreshToken // 有有效token时拉取用户信息 if (request.locals.accessToken && !request.locals.user) { try { request.locals.user = await getUser(request.locals.accessToken) } catch (e) { // token无效清空凭证 request.locals.accessToken = '' request.locals.refreshToken = '' } } const response = await resolve(request) // 原有设置Cookie的逻辑保持不变 const accessToken = `accessToken=${request.locals.accessToken || ''}; Path=/; Secure; HttpOnly;` const refreshToken = `refreshToken=${request.locals.refreshToken || ''}; Path=/; Secure; HttpOnly;` response.headers['set-cookie'] = [accessToken, refreshToken] return response }
内容的提问来源于stack exchange,提问作者John Winston
相关产品推荐
相关产品推荐

