feat(auth): implement user logout functionality
- Add logout action to delete auth cookie and reset user state - Create logout form with enhanced submit handling - Integrate toast notifications for logout feedback - Update sidebar to include logout button with form submission - Remove unnecessary console log in layout server load - Clean up JWT parsing logic in hooks server file - Add new LogoutButton component (currently empty)
This commit is contained in:
@@ -7,10 +7,7 @@ export const handle: Handle = async ({ event, resolve}) =>{
|
||||
const authorization = event.cookies.get(COOKIE_TOKEN_KEY);
|
||||
if (authorization){
|
||||
const split = authorization?.split(' ');
|
||||
|
||||
const token = split[1];
|
||||
|
||||
|
||||
const jwt = parseJwt<JwtPayload>(token);
|
||||
|
||||
if (jwt){
|
||||
|
||||
8
src/lib/components/button/LogoutButton.svelte
Normal file
8
src/lib/components/button/LogoutButton.svelte
Normal file
@@ -0,0 +1,8 @@
|
||||
<script lang="ts">
|
||||
import { enhance } from '$app/forms';
|
||||
import { getContext } from 'svelte';
|
||||
import { TOAST_KEY, type ToastState } from '$lib/stores/toast.svelte.ts';
|
||||
import Icon from '$lib/components/icon/Icon.svelte'; // 假设你的路径
|
||||
|
||||
|
||||
</script>
|
||||
@@ -4,7 +4,9 @@
|
||||
import { fly, fade } from 'svelte/transition';
|
||||
import Icon from '$lib/components/icon/Icon.svelte';
|
||||
import type { NavItem, ProcessedNavItem } from '$lib/types/layout';
|
||||
|
||||
import { getContext } from 'svelte';
|
||||
import { TOAST_KEY, type ToastState } from '$lib/stores/toast.svelte.ts';
|
||||
import { enhance } from '$app/forms';
|
||||
|
||||
|
||||
|
||||
@@ -104,7 +106,26 @@
|
||||
// 使用 $derived 动态计算,类型自动推断为 ProcessedNavItem[]
|
||||
let navItems = $derived(processNavItems(rawNavItems, page.url.pathname));
|
||||
|
||||
// 获取 Toast 以便提示用户
|
||||
const toast = getContext<ToastState>(TOAST_KEY);
|
||||
|
||||
// 处理提交结果的回调
|
||||
const handleLogout = () => {
|
||||
toast.info('正在退出登录...');
|
||||
return async ({ result, update }) => {
|
||||
|
||||
// result.type 可能是 'redirect', 'success', 'failure'
|
||||
if (result.type === 'redirect') {
|
||||
toast.success('您已安全退出');
|
||||
}
|
||||
|
||||
// update() 会触发默认行为(也就是执行 redirect 跳转)
|
||||
await update();
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
let logoutForm: HTMLFormElement;
|
||||
</script>
|
||||
|
||||
<!-- 定义递归 Snippet,显式指定类型 -->
|
||||
@@ -213,11 +234,23 @@
|
||||
<a href="/app/settings"><Icon id="settings" size="16" /> 设置</a>
|
||||
</li>
|
||||
<div class="divider my-1"></div>
|
||||
<li>
|
||||
<button class="text-error" >
|
||||
|
||||
<li class="">
|
||||
<button
|
||||
class="text-error w-full text-left flex items-center gap-2"
|
||||
on:click={() => logoutForm.requestSubmit()}
|
||||
>
|
||||
<Icon id="sign-out" size="16" /> 退出登录
|
||||
</button>
|
||||
</li>
|
||||
<form
|
||||
action="/auth/logout"
|
||||
method="POST"
|
||||
use:enhance={handleLogout}
|
||||
bind:this={logoutForm}
|
||||
hidden
|
||||
>
|
||||
</form>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -7,7 +7,6 @@ import { COOKIE_THEME_KEY } from '$lib/components/constants/cookiesConstants.ts'
|
||||
|
||||
export const load: LayoutServerLoad = async ({url,cookies,locals}) => {
|
||||
|
||||
console.log("locals",locals);
|
||||
const targetPath: RouteId = '/app/dashboard';
|
||||
|
||||
if (url.pathname === '/') {
|
||||
|
||||
17
src/routes/auth/logout/+page.server.ts
Normal file
17
src/routes/auth/logout/+page.server.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import type { Actions } from './$types';
|
||||
import { redirect } from '@sveltejs/kit';
|
||||
|
||||
import { resolve } from '$app/paths';
|
||||
|
||||
import { COOKIE_TOKEN_KEY } from '$lib/components/constants/cookiesConstants.ts';
|
||||
|
||||
|
||||
|
||||
export const actions:Actions = {
|
||||
default: async ({ cookies,locals}) => {
|
||||
cookies.delete(COOKIE_TOKEN_KEY,{path:'/'});
|
||||
locals.user = null;
|
||||
|
||||
throw redirect(302, resolve('/'));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user