SvelteKit局域网设备无法设置Cookie导致登录失败求助
问题背景
使用SvelteKit 1.0.0-next.571开发的应用,登录功能在本地http://localhost:5173访问时正常,但局域网内其他设备通过http://192.168.x.x:5173访问时,无法设置登录Cookie,导致登录失败。已尝试调整Cookie的httpOnly、sameSite参数及fetch选项,问题仍未解决。
登录路由包含以下模块:
+page.server.ts:若locals.user已设置则重定向至/+page.svelte:展示登录页面signin/+server.ts:完成登录并从同一机器上的GraphQL应用获取JWT
现有核心代码
signin/+server.ts
[..] let gqlResponse = await response.json(); if ( gqlResponse.errors ) { console.log("ERRORS FROM GRAPHQL MIDDLEWARE:", gqlResponse.errors); return json( { error: gqlResponse.errors, isException: true } ); } if (gqlResponse.data.login.user && !gqlResponse.data.login.error) { opts.cookies.set('jwt', gqlResponse.data.login.token, { path: '/', maxAge: SESSION_MAX_AGE }); opts.setHeaders( { 'Access-Control-Allow-Credentials': 'true' } ) opts.setHeaders({ 'Content-Type': 'application/json' }) } return json( gqlResponse.data.login );
+page.svelte 登录处理代码
[..] const fetchOptions = { method: 'POST', //mode: 'no-cors', //redirect: 'follow' as RequestRedirect, body: JSON.stringify(credentials), credentials: 'include' as RequestCredentials } try { const response = await fetch('/login/signin', fetchOptions); const login = await response.json(); if (login.error) { handleError(login); return false; } } catch (e) { return handleException(e); } goto('/', { replaceState: true, invalidateAll: true} );
解决方案
1. 完善Cookie配置参数
修改signin/+server.ts中Cookie的设置逻辑,添加动态域名、SameSite、httpOnly及secure参数,适配不同访问场景:
opts.cookies.set('jwt', gqlResponse.data.login.token, { path: '/', maxAge: SESSION_MAX_AGE, sameSite: 'lax', // 适配跨域场景,http协议下不能设为'none' domain: new URL(opts.request.url).hostname, // 自动获取当前请求的域名/IP httpOnly: true, // 提升Cookie安全性,避免前端脚本访问 secure: process.env.NODE_ENV === 'production' // 生产环境开启(需HTTPS),开发环境关闭 });
2. 配置SvelteKit开发服务器CORS规则
在svelte.config.js中添加服务器CORS配置,允许凭证传递:
import adapter from '@sveltejs/adapter-auto'; import { vitePreprocess } from '@sveltejs/kit/vite'; /** @type {import('@sveltejs/kit').Config} */ const config = { preprocess: vitePreprocess(), kit: { adapter: adapter(), server: { cors: { origin: true, // 开发环境允许所有来源,生产环境建议指定具体IP/域名 credentials: true // 允许携带凭证(Cookie) } } } }; export default config;
3. 确认Fetch请求配置
保留fetchOptions中的credentials: 'include',不要启用mode: 'no-cors'(该模式会限制响应读取,导致无法处理登录结果)。
4. 重启开发服务器
修改配置后重启SvelteKit开发服务器,确保所有配置生效。
原因说明
- 局域网IP访问时,浏览器将IP视为独立域名,默认Cookie配置未指定
domain,可能触发浏览器安全策略拒绝设置Cookie;动态获取请求hostname可自动适配localhost和IP场景。 - 开发环境为HTTP协议,
secure参数必须设为false,否则浏览器会拒绝设置Cookie。 - SvelteKit开发服务器默认CORS配置未明确允许凭证传递,导致跨origin(localhost与IP属于不同origin)请求时Cookie无法正常设置。
内容的提问来源于stack exchange,提问作者Sten Ka Razin
相关产品推荐
相关产品推荐

