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

SvelteKit中如何通过Auth.js将JWT传递至+page.server.js

SvelteKit + Auth.js 认证流程:JWT传递与用户数据查询问题

问题背景

刚接触SvelteKit和认证开发,用Auth.js实现GitHub登录,期望流程是:
用户登录→SvelteKitAuth返回含用户ID的JWT→访问/dashboard→+page.server.js通过JWT中的ID查询数据库→展示用户数据。

目前已成功生成包含用户ID的JWT,但不清楚如何将JWT传递到+page.server.js和+page.svelte。尝试了从cookie读取token并存入event.locals的方案,但不确定该方案是否合理,也疑惑是否应该从cookie读取token。

当前代码

认证中间件与Auth配置

async function authorization({ event, resolve }) {
    if (event.url.pathname.startsWith('/article')) {
        const token = event.cookies.get('next-auth.session-token');
        const decoded = await decode({ token, secret: SVELTEAUTH_SECRET });
        console.log(decoded);
        if (!token) {
            throw redirect(303, '/auth?redirectSource=articleView');
        }
    }

    return resolve(event);
}

export const handle = sequence(
    SvelteKitAuth({
        providers: [GitHub({ clientId: GITHUB_ID, clientSecret: GITHUB_SECRET })],
        jwt: true,
        secret: SVELTEAUTH_SECRET,
        session: { strategy: 'jwt' },
        callbacks: {
            async jwt({ token, account, profile }) {
                if (account) {
                    token.userId = profile.id;
                }
                return token;
            }
        }
    }),
    authorization
);

解码后的JWT内容

{
  "name": "zerakot",
  "email": "********",
  "picture": "https://avatars.githubusercontent.com/u/49678485?v=4",
  "sub": "49678485",
  "userId": 49678485,
  "iat": 1695501797,
  "exp": 1698093797,
  "jti": "48a73079-bcba-46e4-851e-df5e7a43f089"
}

找到的解决方案代码

async function authorization({ event, resolve }) {
    if (event.url.pathname.startsWith('/article')) {
        const token = event.cookies.get('next-auth.session-token');

        if (!token) {
            throw redirect(303, '/auth?redirectSource=articleView');
        }
        event.locals.token = token;
    }
    return resolve(event);
}

解答与优化方案

1. 从cookie读取token是合理且安全的

Auth.js使用JWT会话策略时,默认会将JWT存储在next-auth.session-token这个HttpOnly Cookie中。HttpOnly属性能阻止前端JavaScript访问该Cookie,有效防范XSS攻击窃取token,这是Auth.js官方推荐的服务端获取token的方式,完全符合安全规范。

2. 优化中间件:直接存储解码后的用户信息

不用把完整token存入event.locals,而是解码后提取需要的用户ID(或其他信息)存入,减少后续页面的重复解码操作,同时避免不必要的token暴露:

import { decode } from '@auth/core/jwt';
import { SVELTEAUTH_SECRET } from '$env/static/private';
import { redirect } from '@sveltejs/kit';

async function authorization({ event, resolve }) {
    // 统一管理需要认证的路径
    const protectedPaths = ['/article', '/dashboard'];
    if (protectedPaths.some(path => event.url.pathname.startsWith(path))) {
        const token = event.cookies.get('next-auth.session-token');
        
        if (!token) {
            // 跳转时保留原路径,登录后可返回
            throw redirect(303, `/auth?redirectSource=${encodeURIComponent(event.url.pathname)}`);
        }

        try {
            const decoded = await decode({ token, secret: SVELTEAUTH_SECRET });
            // 将用户ID存入locals,供后续页面直接使用
            event.locals.userId = decoded.userId;
            // 若需要完整用户信息,也可存入
            // event.locals.user = decoded;
        } catch (error) {
            // token过期或篡改时,强制跳转登录
            throw redirect(303, `/auth?redirectSource=${encodeURIComponent(event.url.pathname)}`);
        }
    }

    return resolve(event);
}

3. 在+page.server.js中使用用户ID查询数据

现在在/dashboard/+page.server.js里可以直接从event.locals获取userId,无需重复处理cookie:

import { db } from '$lib/database'; // 替换为你的数据库连接
import { redirect } from '@sveltejs/kit';

export async function load({ locals }) {
    if (!locals.userId) {
        throw redirect(303, '/auth?redirectSource=/dashboard');
    }

    // 根据userId查询数据库
    const userData = await db.user.findUnique({
        where: { id: locals.userId }
    });

    return { userData };
}

4. 在+page.svelte中展示数据

直接通过load函数返回的data对象获取用户数据:

<script>
    export let data;
</script>

<div class="dashboard">
    <h1>用户仪表盘</h1>
    <p>用户ID: {data.userData.id}</p>
    <p>用户名: {data.userData.name}</p>
    <!-- 其他需要展示的用户信息 -->
</div>

5. 额外优化建议

  • 调整JWT过期时间:Auth.js默认JWT有效期为30天,可根据需求在SvelteKitAuth配置中修改:
SvelteKitAuth({
    // ...其他配置
    session: {
        strategy: 'jwt',
        maxAge: 24 * 60 * 60, // 设置为1天,按需调整
    },
})
  • 前端无需接触JWT:HttpOnly Cookie已经确保token不会被前端获取,前端只需要使用服务端返回的用户数据即可,避免不必要的安全风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 11:31:08