MST
星途 面试题库

面试题:SvelteKit路由守卫中如何处理复杂的权限逻辑

在SvelteKit应用中,权限分为`admin`、`editor`、`viewer`三种。`admin`可访问所有页面,`editor`可访问`/articles`及其子页面,`viewer`仅能访问`/home`和`/about`页面。请详细说明如何设计并实现这种复杂权限逻辑的路由守卫,包括如何存储权限信息,如何在路由守卫中进行判断以及相应的代码实现。
41.2万 热度难度
前端开发Svelte

知识考点

AI 面试

面试题答案

一键面试

1. 存储权限信息

可以使用 localStorageSvelteKitsession 来存储权限信息。这里以 localStorage 为例:

// 登录成功后存储权限信息
function setUserPermission(permission) {
    localStorage.setItem('userPermission', permission);
}

使用 SvelteKitsession 时,在 hooks.server.js 中设置:

import { sequence } from '@sveltejs/kit/hooks';

export const handle = sequence(
    async ({ event, resolve }) => {
        // 假设从数据库或验证逻辑获取权限
        const userPermission = getPermissionFromDatabase(event.locals.user);
        event.locals.session = {
            permission: userPermission
        };
        return resolve(event);
    }
);

2. 路由守卫设计与判断

SvelteKit 中,可以利用 load 函数来实现路由守卫逻辑。

// src/routes/+layout.server.js
import { redirect } from '@sveltejs/kit';

export const load = async ({ locals }) => {
    const requiredPermissions = {
        '/': ['viewer'],
        '/about': ['viewer'],
        '/articles': ['editor', 'admin'],
        '/articles/*': ['editor', 'admin']
    };
    const currentRoute = this.route.id;
    const userPermission = locals.session?.permission;
    if (!userPermission) {
        throw redirect(302, '/login');
    }
    const allowedPermissions = requiredPermissions[currentRoute];
    if (!allowedPermissions.includes(userPermission)) {
        if (userPermission === 'viewer') {
            throw redirect(302, '/home');
        } else {
            throw redirect(302, '/login');
        }
    }
    return {};
};

3. 完整代码实现

登录逻辑(示例)

<!-- src/routes/login.svelte -->
<script>
    import { setUserPermission } from '$lib/utils/auth';
    const handleSubmit = (event) => {
        event.preventDefault();
        const formData = new FormData(event.target);
        const username = formData.get('username');
        const password = formData.get('password');
        // 模拟登录验证
        const user = { username, password, permission: 'viewer' };
        if (user) {
            setUserPermission(user.permission);
            // 重定向到首页
            window.location.href = '/';
        }
    };
</script>

<form on:submit={handleSubmit}>
    <label for="username">Username:</label>
    <input type="text" id="username" name="username" required />
    <label for="password">Password:</label>
    <input type="password" id="password" name="password" required />
    <button type="submit">Login</button>
</form>

路由守卫逻辑(+layout.server.js

// src/routes/+layout.server.js
import { redirect } from '@sveltejs/kit';

export const load = async ({ locals }) => {
    const requiredPermissions = {
        '/': ['viewer'],
        '/about': ['viewer'],
        '/articles': ['editor', 'admin'],
        '/articles/*': ['editor', 'admin']
    };
    const currentRoute = this.route.id;
    const userPermission = locals.session?.permission;
    if (!userPermission) {
        throw redirect(302, '/login');
    }
    const allowedPermissions = requiredPermissions[currentRoute];
    if (!allowedPermissions.includes(userPermission)) {
        if (userPermission === 'viewer') {
            throw redirect(302, '/home');
        } else {
            throw redirect(302, '/login');
        }
    }
    return {};
};

上述代码展示了如何在 SvelteKit 应用中实现复杂权限逻辑的路由守卫,包括权限信息的存储和在路由守卫中的判断逻辑。实际应用中,需要根据具体业务场景进行调整,如从数据库中获取真实权限信息等。