我的问题很简单。您如何预防,例如非授权用户,是否可以在sapper中输入特定路线?
user.svelte
<script>
import { onMount } from 'svelte';
onMount(() => {
if(!authenticated)
window.history.back()
});
</script>
在安装到DOM之前是否可以选择运行一些代码?
您如何解决此类问题?
谢谢。
答案 0 :(得分:3)
我不能说这是对的。这就是我在SPA中所做的。如果我想保护我的应用程序的所有路由。我在_layout.svelte
顶级文件中创建了以下文件。
<script context="module">
import {ax} from './_parts/Helper.svelte'
import {admin, adminName} from './store'
import {goto} from '@sapper/app'
export async function preload(page) {
try {
const {data} = await ax.get('/admin/is-logged-in')
adminName.set(data)
admin.set(true)
} catch (e) {
admin.set(false)
}
}
</script>
<script>
import Login from './admin/login.svelte'
import {loading} from './store.js'
</script>
<main>
{#if $admin}
<slot></slot>
{:else}
<Login />
{/if}
</main>
ax
并不神奇。它只是配置了axios。
'/admin/is-logged-in'
是您在后端检查会话的地方。
答案 1 :(得分:1)
让我概括一下这个问题。 我们应该在客户端和后端之间实现会话状态同步。 最好的方法是什么?这是一个难题。这取决于。
例如,如果您在远程用户尝试访问受限区域时尝试保护有价值的东西,这非常简单。只需重定向到登录/注册页面即可。但是,如果一个远程用户注销而第二个用户尝试在从后端重新加载之前尝试在同一浏览器上使用同一应用程序登录怎么办?我们很快跳到了逻辑陷阱。那么,如何根据远程会话状态正确地使用DOM树进行操作?
可能最好的方法是控制路线之间的过渡。 在sapper中,应该通过为每个模块导出preload函数来实现这一点。
因此,请将逻辑放入_layout.svelte(在我看来,这很简单,但不是简单的方法)。我们以创建一个通用模块route-guards.js
为例。
然后,我们应该将其导入每个模块中。
其余的答案:
// route-guards.js
export async function transitionControl(self, page, session) {
const result = await self.fetch('/is-logged-in'); // self for support server side rendering
const response = await result.json();
if (!response && page.path !== '/login') {
return self.redirect(302, '/login');
}
}
<!-- any module.svelte -->
<script context="module">
import { transitionControl } from "./route-guards";
export async function preload(page, session) {
await transitionControl(this, page, session);
// Do another what you want before page load
}
</script>
请记住,两件事之间的同步状态绝非易事。 OMG网站开发如此困难。谢谢大家的关注。
答案 2 :(得分:0)
我认为我有基本相同的问题。我在这里在SO上发布了question (with solution),并于当天在Sapper GitHub的this issue的帮助下使用了自己的“ 身份验证重定向中间件”解决了该问题。
答案 3 :(得分:0)
感谢Yousuf的回答。我对此进行了修改,并提出了一个替代解决方案,如果用户未登录,该解决方案将重定向到登录页面。
我也不希望所有路由都受到保护,因为用户必须能够登录和注册。因此,我使用页面对象来确定用户想要导航到的路线,并且还检查会话对象是否存在登录令牌(例如JWT)。可以根据您的需要修改此支票。
_layout.svelte
<script context="module">
const publicRoutes = ['/login', '/register'];
export async function preload(page, session) {
if (publicRoutes.indexOf(page.path) === -1 && !session.token) {
this.redirect('302', 'login');
}
}
</script>
... The rest of your component here ...