我的问题很简单。您如何防止(例如非授权用户)在工兵中输入特定路线?
用户.svelte
<script>
import { onMount } from 'svelte';
onMount(() => {
if(!authenticated)
window.history.back()
});
</script>
在安装到 DOM 之前是否有任何选项可以运行一些代码?
您如何解决此类问题?
谢谢你。
我不能说这是正确的。这就是我在我的 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'
是您在后端检查会话的地方。
我认为我遇到了基本相同的问题。我在 SO 上发布了问题(带有解决方案),并在同一天在 Sapper GitHub 的这个问题的帮助下用我自己的“身份验证重定向中间件”解决了这个问题。
让我概括一下这个问题。我们应该在客户端和后端之间实现会话状态同步。最好的方法是什么?这是一个很难的问题。这取决于。
例如,如果您在远程用户尝试访问受限区域时尝试保护有价值的东西,这非常简单。只需重定向到登录/注册页面。但是,如果一个远程用户注销和第二个用户在从后端重新加载之前尝试在同一个浏览器上登录同一个应用程序怎么办?我们很快就跳到了逻辑陷阱。那么如何根据远程会话状态正确操作 DOM 树呢?
可能是最好的方法,只需控制路线之间的转换。在 sapper 中,您应该通过导出每个模块的预加载函数来做到这一点。
因此,改为将逻辑放入 _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 Web 开发太难了。谢谢大家关注。
感谢优素福的回答。我对其进行了修改,并提出了一个替代解决方案,如果用户未登录,它会重定向到登录页面。
我也不希望所有路由都受到保护,因为用户必须能够登录和注册。因此,我使用页面对象来确定用户想要导航到的路线,并且如果存在登录令牌(例如 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 ...