实现退出登录

退出登录

在后台开发逻辑,所以关于登录的处理建议大家都在store去完成。不要在外面额外定义操作。比如:登录,获取用户信息,获取token,获取角色,获取权限都在这里。包括退出登录。

1: 修改store/modules/user.js

  • 在actions 定义异步方法去请求服务器进行服务器退出。这里会调用一个服务器的退出接口,并且调用mutations的清除state状态管理的方法
  • 在mutations定义清除状态管理的方法。
  • 清除完毕,使用router重定向到登录页面。

为什么一定要这做:因为state的数据只能通过mutations进行管理和操作。

01、定义服务器接口

/**
     * 退出登录
     * @param request
     * @return
     */
    @PostMapping("/login/logout")
    @PugDoc(name = "退出登录")
    public String logout(HttpServletRequest request) {
        // 通过请求头获取
        String token = jwtService.getToken(request);
        String userId = jwtService.getTokenUserId(request);
        Vsserts.isEmptyEx(token, AdminUserResultEnum.TOKEN_NOT_FOUND);
        Vsserts.isNullEx(userId, AdminUserResultEnum.USER_NAME_NOT_EMPTY);
        // 删除下线的uuid
        String tokenUuidKey = USER_LOGIN_LOGOUT_KEY + userId;
        stringRedisTemplate.delete(tokenUuidKey);
        // 删除续期redis的key
        String tokenKey = USER_LOGIN_TOKEN_KEY + token;
        stringRedisTemplate.delete(tokenKey);
        // 加黑名单,防止下次使用,它可能是在刚刚生成的时候就退出了。退出逻辑一定力求不管你token有效还是过期都应该后续不能在使用
        jwtBlackService.addBlackList(token);
        // 退出登录
        return "success";
    }

02、定义退出接口调用

services/LoginService.js定义退出接口

import request from '@/utils/request'

export default {

    /**
     * 登录逻辑
     * @param {} user 
     * @returns 
     */
    toLogin(user) {
        return request.post("/login/toLogin", user);
    },

    /**
     * 退出逻辑
     * @returns 
     */
    toLogout() {
        return request.post("/login/logout");
    }


}

03、定义store管理退出功能

在store/modules/user.js中定义actions和mutations的相关退出逻辑,如下:

import loginService from '@/services/login/LoginService';

export default {
    namespaced: true,
    // 定义全局状态管理的响应式数据
    state() {
        return {
            // 管理的用户对象信息
            userId: "",
            username: "",
            avatar: "",
            token: "",
            roleList: [],
            permissionList: []
        }
    },

    // 定义修改状态管理的方法
    // 结论:修改state的全局状态数据只能通过mutations的方法进行修改。
    // 调用通过:store.commit方法执行和调用
    mutations: {
        // 同步state中用户的信息
        toggleUser(state, serverUserData) {
            state.token = serverUserData.token;
            state.tokenUuid = serverUserData.tokenUuid;
            state.userId = serverUserData.user.id;
            state.username = serverUserData.user.username;
            state.avatar = serverUserData.avatar;
            state.roleList = [{ name: "管理员" }];
            state.permissionList = [{ code: "-1" }];
        },

        // 清除状态
        clearUser(state) {
            state.userId = "";
            state.account = "";
            state.avatar = "";
            state.token = "";
            state.roleList = [];
            state.permissionList = [];
            // 这里记得把持久化的状态管理清除。这里不执行也可以
            //localStorage.removeItem("pug-admin-web-vuex");
        }
    },

    // 异步修改状态的的方法
    // 注意:actions定义的方式,不能直接修改state的状态数据
    // 只能通过context.commit去条件mutations的方法去修改state的数据。它是一个间接的方式
    // 调用通过:store.dispatch方法执行和调用
    actions: {
        async toLogout(context) {
            //1: 异步请求去执行服务器退出操作
            //2: 执行页面状态清空
            try {
                // 清楚本地状态和缓存相关信息
                context.commit("clearUser");
                // 获取服务端的返回操作
                var serverResponse = await loginService.toLogout();
                // 返回,这里是promise
                return Promise.resolve(serverResponse);
            } catch (err) {
                // 为什么不在这里处理呢,因为在这里没有办法和页面进行交互。
                // 抛出给谁用,肯定是具体调用者去捕获,和java异常抛出一模一样的概念呢
                return Promise.reject(err);
            }
        },

        // 从登录以后的axios请求中获取serverUserData
        async toLogin(context, loginUserData) {
            try {
                // 发起登录请求
                const serverResponse = await loginService.toLogin(loginUserData);
                // 通过context.commit去修改mutations中toggleUser去同步state数据
                context.commit("toggleUser", serverResponse.data);
                // 返回,这里是promise
                return Promise.resolve(serverResponse);
            } catch (err) {
                // 为什么不在这里处理呢,因为在这里没有办法和页面进行交互。
                return Promise.reject(err);
            }
        }
    },

    // 对state数据的改造和加工处理。给未来的页面和组件进行调用。
    // 从而达到一个封装的目录 computed
    getters: {
        // 组装一个角色信息返回
        getRoleName(state) {
            return state.roleList.map(role => role.name).join(",");
        },
        // 获取权限
        getPermissions(state) {
            return state.permissionList.map(role => role.code);
        },
        // 获取用户ID
        getUserId(state) {
            return state.userId;
        },
        // 获取token
        getToken(state) {
            return state.token;
        },
        // 获取tokenUuid 用于同一账号挤下线
        // 因为你每次登录都会产生新的uuid。所以旧的就被你新挤掉
        getTokenUuid(state) {
            return state.tokenUuid;
        },
        // 判断是否登录
        isLogin(state) {
            return state.userId != "";
        }
    }
}

03、调用退出功能接口

<template>
    <h1>后台首页</h1>
    <p>登录的信息是:{{store.state.user.username}}</p>
    <button @click="handleLogout">退出</button>
</template>

<script setup>

    import { useStore} from 'vuex';
    import { useRouter} from 'vue-router';
    const store = useStore();
    const router = useRouter();

    const handleLogout = ()=>{
        if(confirm("你确定退出登录吗?")){
            store.dispatch("user/toLogout").then(logoutRes=>{
                // 这里肯定是退出成功才会进入
                router.push("/toLogin");
            });
        }
    }
</script>

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙崎流河

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值