gpt4 book ai didi

javascript - Svelte Sapper 在页面刷新时保留 session (重新加载)

转载 作者:行者123 更新时间:2023-12-03 16:58:46 26 4
gpt4 key购买 nike

我最近才开始使用 sveltesapper ,并且即使用户刷新页面,我也试图保持存储的 session 。 (我希望这可以做到)。
这个想法是用户可以登录,并作为经过身份验证的用户被重定向到主页。
但是当我在浏览器中点击刷新时, session 是空的,用户必须重新进行登录过程。
有任何想法吗?
到目前为止,我找不到解决方案。下面的一些文件涉及此过程。server.js

import sirv from "sirv";
import polka from "polka";
import compression from "compression";
import * as sapper from "@sapper/server";
import bodyParser from "body-parser";
import session from "express-session";
import sessionFileStore from "session-file-store";

const { PORT, NODE_ENV } = process.env;
const dev = NODE_ENV === "development";
const FileStore = sessionFileStore(session);

polka()
.use(
bodyParser.json(),
session({
secret: "secret",
resave: false,
saveUninitialized: true,
cookie: {
maxAge: 31536000,
},
store: new FileStore({
path: process.env.NOW ? `/tmp/sessions` : `.sessions`,
}),
})
)
.use(
compression({ threshold: 0 }),
sirv("static", { dev }),
sapper.middleware({
session: (req) => ({
user: req.session && req.session.user,
}),
})
)
.listen(PORT, (err) => {
if (err) console.log("error", err);
});
login.svelte
<script context="module">
export async function preload({ params }, { user }) {
if (user) {
this.redirect(302, `/`);
}
}
</script>

<script>
import { goto, stores } from "@sapper/app";
import api from "../api.js";
import Button from "../components/Button.svelte";
import Input from "../components/Input.svelte";
import InputPassword from "../components/InputPassword.svelte";

let errors;
let email;
let password;
let disabled;

const { session } = stores();

const handleSubmit = async () => {
try {
errors = null;
disabled = true;
await api.get("/csrf-cookie");
const authToken = await api.post("/login", { email, password });
api.defaults.headers.common["Authorization"] = `Bearer ${authToken.data}`;
const user = await api.get("/me");
session.set({ user: user.data });
disabled = false;
goto("/");
} catch (e) {
errors = e;
disabled = false;
}
};
</script>

<style>
.login-form {
max-width: 35em;
margin: 5% auto;
padding: 2em;
background: rgba(233, 233, 233, 0.5);
border: 1px solid rgba(151, 151, 151, 0.5);
border-radius: 5px;
}

.form-title {
margin-top: 0;
font-size: 1.2em;
}

.error-block {
color: red;
}
</style>

<svelte:head>
<title>Login</title>
</svelte:head>

<div class="login-form">
<h3 class="form-title">Login</h3>
<form on:submit|preventDefault={handleSubmit}>
<Input placeholder="Username" id="email" bind:value={email} />
<InputPassword placeholder="Password" id="password" bind:value={password} />
<Button {disabled} type="submit">Login</Button>

{#if errors}<span class="error-block">{errors}</span>{/if}
</form>
</div>
index.svelte
<script context="module">
export async function preload({ params }, { user }) {
console.log(user); // undefined
if (!user) {
this.redirect(302, `/login`);
}
}
</script>

<h1>Dashboard</h1>
我正在使用 Laravel 8 sanctum对于身份验证。
不知道我还需要提供什么来解决这个问题。

最佳答案

看起来好像您从 sapper realworld 中提取了大部分代码。项目(如果我错了,请纠正我),但是您忘记实现服务器端“api 路由”以将新登录的用户添加到 session 中。
在现实世界的项目中,当用户登录时,会向服务器端发出 POST 请求 /auth/login路线,由以下功能提供服务:

import * as api from 'api.js';

export function post(req, res) {
const user = req.body;

api.post('users/login', { user }).then(response => {
if (response.user) req.session.user = response.user;
res.setHeader('Content-Type', 'application/json');

res.end(JSON.stringify(response));
});
}
这个函数的作用是:
  • 它将请求转发给 /users/login realworld project API 的端点
  • 如果对该请求的响应包含 user对象,它将该对象存储到服务器端 session
  • 它将原始 API 响应以 JSON 形式返回给应用程序,用于填充 session 存储(如果原始响应包含用户对象)

  • 考虑到您显然没有使用真实世界的项目 API 进行身份验证,而是您自己的身份验证过程,您必须添加的是与上述类似的服务器端路由,但会:
  • 将登录请求中继到您自己的进程,
  • 字段响应并使用该响应设置 session 用户,
  • 最后将响应传递给客户端(或者,将存储到 session 中的用户对象或错误消息传递给客户端)。

  • 考虑到您在代码中用于在客户端设置用户的 API 调用,该函数看起来像这样(例如,将该文件保存为 /routes/auth/login.js):
    import * as api from 'api.js';

    export async function post(req, res) {
    const { email, password } = req.body;
    const authToken = await api.post("/login", { email, password });
    api.defaults.headers.common["Authorization"] = `Bearer ${authToken.data}`;
    const user = await api.get("/me");
    if (user) req.session.user = user.data;
    res.setHeader('Content-Type', 'application/json');
    res.end(JSON.stringify(user));
    }
    handleSubmit您的 login.svelte 中的方法文件变为:
      const handleSubmit = async () => {
    try {
    errors = null;
    disabled = true;
    // substitute your auth API request chain with a proxy request to
    // the server-side API where you will set the server-side session user
    const user = await fetch('/auth/login', {
    method: 'POST',
    credentials: 'include',
    body: JSON.stringify({ email, password }),
    headers: { 'Content-Type': 'application/json' },
    })
    session.set({ user: user.data });
    disabled = false;
    goto("/");
    } catch (e) {
    errors = e;
    disabled = false;
    }
    };
    请注意,在您的特定情况下,您可能还希望将身份验证 token 存储在 session 中,以避免每次要向数据 API 发出经过身份验证的请求时都必须请求新 token 。

    关于javascript - Svelte Sapper 在页面刷新时保留 session (重新加载),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64412746/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com