首页 > 其他分享 >Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二

时间:2023-09-18 15:05:43浏览次数:50  
标签:wiki 10 登录 -- Spring oss process com image

接着Spring Boot&Vue3前后端分离实战wiki知识库系统<十二>--用户管理&单点登录开发一继续往下。

登录功能开发: 

接下来则来开发用户的登录功能,先准备后端的接口。

后端增加登录接口:

1、UserLoginReq:

先来准备用户登录的请求实体:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_spring

package com.cexo.wiki.req;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Pattern;

public class UserLoginReq {

    @NotEmpty(message = "【用户名】不能为空")
    private String loginName;

    @NotEmpty(message = "【密码】不能为空")
    // @Length(min = 6, max = 20, message = "【密码】6~20位")
    @Pattern(regexp = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,32}$", message = "【密码】规则不正确")
    private String password;

    public String getLoginName() {
        return loginName;
    }

    public void setLoginName(String loginName) {
        this.loginName = loginName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName());
        sb.append(" [");
        sb.append("Hash = ").append(hashCode());
        sb.append(", loginName=").append(loginName);
        sb.append(", password=").append(password);
        sb.append("]");
        return sb.toString();
    }
}

对于用户登录,只需要用户名和密码既可,其中有一个小细节需要说明一下,就是对于之前后台实现的用户管理保存的实体其密码是做了非常详细的规则提示的:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_spring_02

而这里对于用户登录的密码规则校验,则不能提示这么详情了,因为提示这么详情容易被人根据规则来进行密码破解,所以这里就提示了一个比较模糊的校验提示:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_springboot_03

2、UserLoginResp:

再来准备登录的response实体:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_springboot_04

package com.cexo.wiki.resp;

public class UserLoginResp {
    private Long id;

    private String loginName;

    private String name;

    private String token;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getLoginName() {
        return loginName;
    }

    public void setLoginName(String loginName) {
        this.loginName = loginName;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }

    @Override
    public String toString() {
        return "UserLoginResp{" +
                "id=" + id +
                ", loginName='" + loginName + '\'' +
                ", name='" + name + '\'' +
                ", token='" + token + '\'' +
                '}';
    }
}

3、Controller增加登录接口:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_redis_05

4、Service实现登录逻辑:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_springboot_06

那接下来咱们是直接来校验用户名和密码的正确性么?其实应该先校验用户名是否存在,如果不存在,则密码都没密要校验了,所以先来查一下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_redis_07

而处理异常可以采用在之前用户管理保存时的方式,抛出异常:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_08

这里咱们先定义一个用户名不存在的异常码:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_vue3_09

这里提示语貌似写错了吧。。其实这里是故意写一个模糊的提示的,因为给用户提示得越详细,越容易被攻击,所以这种风险意识在做项目时是很重要的。好,接下来就可以抛出这个异常了:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_redis_10

接下来再来判断密码的正确性:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_11

最后,还有一个细节,就是目前这两块给用户提示了一个一模一样的提示:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_springboot_12

很明显这对于后端排错不太好,所以有必要针对这俩加点日志:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_13

前端增加登录模态框:

效果:

先来看一下登录的效果:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_spring_14

实现:

1、增加登录入口:

接下来则先在前端页面中增加一个用户登录的入口,这里很明显是应该在头部区域加,也就是:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_springboot_15

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_16

此时的效果:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_redis_17

另外这里既然改了头部区域,左上角这块的logo也顺带改一下,目前这里是一个色块,没有什么实际意义,这里改一下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_redis_18

控制它的css在这:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_springboot_19

这里将这个logo的css先去掉,在头部组件里来定义就成:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_vue3_20

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_springboot_21

然后修改为:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_springboot_22

此时效果:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_spring_23

2、 点击弹出模态登录窗口:

先来给登录这个a标签增加点击事件:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_redis_24

而模态框的处理在之前的页面中已经多次用到了,所以这里就不过多解释了,直接准备一个登录的模态框:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_25

其中提交的时候得请求接口,需要耗时,交互上肯定需要有loading等待效果,所以先提前把响应式的变量定义好:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_springboot_26

此时运行看一下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_vue3_27

3、登录点击事件添加:

接下来给模拟框增加一个提交事件:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_springboot_28

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_29

这里为了使用方便,给表单输一个默认值,如下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_redis_30

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_31

此时运行:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_spring_32

4、发起登录请求:

最后发起登录请求,这块的网络请求代码也没啥好说的,直接copy原来的逻辑改下接口就可以了,如下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_33

其中需要导两个组件:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_springboot_34

好,此时运行看一下效果:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_redis_35

成功登录。

登录成功处理并集成vuex:

 目前我们已经登录成功,但是登录成功之后,其实就给了一个提示,没有做登录成功之后的逻辑处理,接下来咱们则来完善它。

后端保存用户信息:

1、集成Redis:

由于需要将用户登录成功的信息以token形式存到Redis当中,所以先在工程中集成它:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_redis_36

而关于Redis的环境的配置这里就不说明了,当时在https://www.cnblogs.com/webor2006/p/14999543.html这篇已经详细学习过了,这块网上资料也比较多,我本机装好之后,先使用此命令启动一下它:

redis-server

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_vue3_37

然后再用可视化的图形工具RDM连接看一下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_38

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_39

目前里面没有存任何信息,所以数量都是0,然后再配置一下redis的数据源,类似于mysql一样:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_vue3_40

2、登录时生成token并存入Redis中:

此时我们就需要修改一下登录的逻辑时,在登录成功之后,需要生成一个token,这里就用之前使用的雪花算法来生成,如下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_redis_41

此时则需要将token存入到Redis当中,此时需要这么来做:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_spring_42

其中有个细节需要注意,我们目前存放到Redis中是将实体转换成了一个json串了:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_redis_43

如果想直接保存实体,注意需要让实体实现序列化的接口,不然保存的时候会报如下异常:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_vue3_44

另外此token信息也需要返回给前端,因为之后前端也需要将此token信息在请求时携带上进行身份的识别,所以:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_vue3_45

其中为了调试方便,将这块加个日志输出:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_vue3_46

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_47

3、测试:

接下来咱们来登录测试一下是否写入成功了:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_spring_48

显示是成功了,到RDM可视化工具中刷新查看一下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_spring_49

貌似是有了,不过看了是一串乱码,为了验证这个token写入到Redis是没有问题的,下面在TestController中增加测试方法,如下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_vue3_50

然后咱们就可以这样来测试了:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_redis_51

咱们运行一下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_spring_52

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_springboot_53

那对于这里的登录时,生成这么一个token:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_spring_54

此时借助这个测试能查出存在redis中的用户信息么?

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_vue3_55

木问题。

前端显示登录用户:

接下来在用户登录成功之后,则需要显示出用户的昵称,修改页面:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_spring_56

其中user是一个响应式的变量,定义一下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_springboot_57

另外由于数据库中用户test的密码是test123,所以这里改一下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_58

然后在登录成功之后则给它进行赋值,如下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_redis_59

接下来在登录入口处增加显示与隐藏的控制:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_redis_60

接下来运行看一下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_springboot_61

集成vuex:

说明:

接下来说明一个问题,就是目前我们登录后信息是在头部组件中来保存的:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_springboot_62

那如果我想在底部组件里也能拿到用户的登录信息该怎么办呢?

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_springboot_63

很明显是拿不到的,因为定义的头部的响应式变量不能在其它页面使用,此时就得声明一个全局的变量来进行存储,这里就需要使用到vuex了,度娘先了了解一下它:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_spring_64

哦,就是来解决多组件数据通信的问题的,刚好符合我们目前的使用场景,而使用它的位置就在这块:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_65

接下来咱们则来使用一下它。

实现:

1、定义一个全局的变量:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_redis_66

2、定义操作变量的函数:

光定义变量还不行,得定义操作它的行为,这里则会涉及到如下两处:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_67

其中mutations是同步函数,而actions是支持异步的,这里我们在mutations中来进行定义:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_68

3、返回store:

最后需要将这个store返回出去,以便可以在其它界面进行使用:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_vue3_69

4、使用store保存用户信息:

接下来我们回到头部组件中,在登录成功之后使用store来保存一下用户信息,写法如下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_vue3_70

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_springboot_71

5、底部组件中获取用户信息:

接下来咱们就可以使用这个全局的数据了:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_springboot_72

其中computed的含义是:如果一个响应式变量是要根据某个变量的变化而计算得来,就可以使用computed。

其中这里有个代码可以简化一下,就是它:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_vue3_73

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_spring_74

6、运行:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_spring_75

所以vuex其实就是全局响应式的变量,单纯的组件里面的响应式变量是做不到这种效果的。

最后更改一个文案:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_springboot_76

而它应该受登录状态的控制,所以加一个显隐逻辑:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_77

再来运行一下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_springboot_78

使用sessionStorage解决刷新数据丢失的问题:

说明:

接下来再来看一个问题:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_springboot_79

刷新之后,登录态就没有了,这也反应出vuex有问题,浏览器一刷新就没有了,而要解决这个问题就需要使用sessionStorage了,度娘又来了解一下它: 

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_vue3_80

其中标红的是一些关于它值得关注的,它会随着浏览器页面的存在而存在,如果关闭页面了则数据就不存在了,在搜它的概念时,还搜到了一个在前端经常会提及的话题https://blog.csdn.net/weixin_45541388/article/details/125367823

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_redis_81

关于这块自己网上了解一下既可。

实现:

1、拷一个工具类:

为了使用sessionStorage,拷一个工具类进来:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_redis_82

SessionStorage = {
    get: function (key) {
        var v = sessionStorage.getItem(key);
        if (v && typeof (v) !== "undefined" && v !== "undefined") {
            return JSON.parse(v);
        }
    },
    set: function (key, data) {
        sessionStorage.setItem(key, JSON.stringify(data));
    },
    remove: function (key) {
        sessionStorage.removeItem(key);
    },
    clearAll: function () {
        sessionStorage.clear();
    }
};

为啥要封装一下呢,因为默认的sessionStorage只支持存string,这里扩展保存一个object类型,其实也就是最终会将object转换成Json字符串再保存:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_spring_83

2、引入工具类:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_vue3_84

3、使用sessionStorage:

接下来我们在保存user信息时,除了使用vuex保存在全局响应式的变量当中之外,还需要保存到sessionStorage,所以好的做法就是在vuex这个文件中进行处理,先来引入工具类,引入的方法还记得不,其实在之前md5工具方法时已经使用过了,回忆一下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_85

所以定义一下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_vue3_86

其中let后面的名称取的是js中定义的它:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_vue3_87

然后在获取用户信息时加上从sessionStorage来取的逻辑:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_spring_88

另外在设置user信息时,则需要将其存到SessionStorage当中:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_89

其中有个代码可以优化一下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_90

都是常量,可以将其提取一下,提高维护性:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_spring_91

接下来运行看一下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_spring_92

其中可以看到footer下的用户登录信息在浏览器刷新之后是能够被保留的,而关闭浏览器当前窗口就清空了,符合SessionStorage的定义场景,只是右上角的header用户信息在浏览器刷新时没有保留住,是因为header页面的user变量没有改成computed,如footer页面报写的这样:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_spring_93

所以咱们将header的代码改成这样:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_redis_94

将其改为:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_95

这样就会去监听store中user的变化,不过这样改之后有个报错:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_springboot_96

这里就没必要了,直接将user保存到store中就可以了:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_spring_97

接下来运行看一下效果:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_98

成功修复浏览器刷新用户信息被清空的问题。

增加退出登录功能:

1、UserController.logout():

对于退出登录的接口其实只需要传一个token参数既可,所以定义接口如下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_spring_99

其实也就是根据token将redis对应的信息给删除既可。

2、前端增加退出按钮:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_100

而通常退出操作是需要给用户一个确认提示的,所以在它外层再包装一层:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_101

3、调用退出登录接口:

接下来咱们就可以处理退出登录的点击事件,如下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_springboot_102

4、运行:

接下来运行看一下效果,发现后台报错了:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_redis_103

这是因为登出接口是一个get请求,而我们在后台声明的是:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_vue3_104

修改一下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_vue3_105

再运行:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_vue3_106

这里貌似界面上看着有点别扭,就是退出登录一般是在用户登录信息的右侧的,现在在左侧:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_redis_107

更改一下顺序:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_108

因为login-menu的样式是:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_109

最上面的元素就在最右侧边了,最后的样子:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_springboot_110

增加登录校验:

有了用户登录之后, 对于页面中的功能则需要进行登录的校验了,对于管理类的入口都是需要登录之后才能预览,而对于文章查看是不需要的,所以,接下来进行登录校验的处理。

后端增加拦截器,校验token有效性:

1、 新建一个拦截器LoginInterceptor:

对于拦截器在之前已经有使用过了:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_redis_111

同样的,对于这个登录拦截器写法也差不多,关于这块的代码就不过多解释了,比较好理解:

package com.jiawa.wiki.interceptor;

import com.alibaba.fastjson.JSON;
import com.jiawa.wiki.resp.UserLoginResp;
import com.jiawa.wiki.util.LoginUserContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 拦截器:Spring框架特有的,常用于登录校验,权限校验,请求日志打印
 */
@Component
public class LoginInterceptor implements HandlerInterceptor {

    private static final Logger LOG = LoggerFactory.getLogger(LoginInterceptor.class);

    @Resource
    private RedisTemplate redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 打印请求信息
        LOG.info("------------- LoginInterceptor 开始 -------------");
        long startTime = System.currentTimeMillis();
        request.setAttribute("requestStartTime", startTime);

        // OPTIONS请求不做校验,
        // 前后端分离的架构, 前端会发一个OPTIONS请求先做预检, 对预检请求不做校验
        if (request.getMethod().toUpperCase().equals("OPTIONS")) {
            return true;
        }

        String path = request.getRequestURL().toString();
        LOG.info("接口登录拦截:,path:{}", path);

        //获取header的token参数
        String token = request.getHeader("token");
        LOG.info("登录校验开始,token:{}", token);
        if (token == null || token.isEmpty()) {
            LOG.info("token为空,请求被拦截");
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            return false;
        }
        Object object = redisTemplate.opsForValue().get(token);
        if (object == null) {
            LOG.warn("token无效,请求被拦截");
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            return false;
        } else {
            LOG.info("已登录:{}", object);return true;
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        long startTime = (Long) request.getAttribute("requestStartTime");
        LOG.info("------------- LoginInterceptor 结束 耗时:{} ms -------------", System.currentTimeMillis() - startTime);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//        LOG.info("LogInterceptor 结束");
    }
}

逻辑简单来说的话就是先来判断token是否为空,如果不为空,则再到redis中来获取一下。其中校验不通过时,返回一个401:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_112

2、配置拦截器:

接下来要想拦截器生效,则需要到这来配置一下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_redis_113

然后接下来得进行一下配置,因为有些接口是需要进行登录拦截的,如下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_114

package com.cexo.wiki.config;

import com.cexo.wiki.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.annotation.Resource;

@Configuration
public class SpringMvcConfig implements WebMvcConfigurer {

    //    @Resource
//    LogInterceptor logInterceptor;//配置拦截器
    @Resource
    LoginInterceptor loginInterceptor;

    public void addInterceptors(InterceptorRegistry registry) {
//        registry.addInterceptor(logInterceptor)
//                .addPathPatterns("/**");
        registry.addInterceptor(loginInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns(
                        "/test/**",
                        "/redis/**",
                        "/user/login",
                        "/category/all",
                        "/ebook/list",
                        "/doc/all/**",
                        "/doc/vote/**",
                        "/doc/find-content/**",
                        "/ebook-snapshot/**"
                );
    }
}

其中这里用到了“**”:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_spring_115

则表示是任意值,好,加了拦截器之后咱们再来访问一下页面:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_vue3_116

首页查看电子书都正常,但是点击用户管理时,页面的数据加载不出来了,查看一下后台日志,其实就是这个登录拦截器给拦了:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_vue3_117

前端请求增加token参数:

目前后端加了token校验之后,在前端则需要在请求头中增加token信息了,很显然也需要在统一接口拦截器中来进行处理,那vue中是如何处理的呢?其实使用的网络组件axios就有相应的处理办法,这块其实在之前https://www.cnblogs.com/webor2006/p/17182186.html已经使用过了:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_vue3_118

所以在这里加上token信息的逻辑:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_redis_119

此时再运行你会发现用户管理模块在登录之后内容还是出不来,这里就有一个坑需要说明一下,就是这块:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_spring_120

但是在用户登录时往Redis写入时:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_121

这样类型就不匹配了,所以需要这样改一下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_springboot_122

此时再运行看一下效果:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_123

可以看到在登录之后再查询用户管理的列表就出来了,可见现在的token的校验已经是好使了。

前端页面增加登录校验:

未登录时,管理菜单要隐藏:

现在对于管理界面在用户没有登录时也能被看到,很显然是不合理的,所以接下来处理一下它:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_vue3_124

根据之前的经验,对于元素的显隐可以用它:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_springboot_125

挺简单,但是你运行发现不好使,反而是把这个v-show加到<router-link>中可以:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_spring_126

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_spring_127

但是还是有瑕疵,就是隐藏时这个会占用宽度:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_用户登录_128

此时就需要自己来写css样式了,如下处理:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_vue3_129

解释一下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_redis_130

而如果没登录,则需要将元素给隐藏,注意这里的style里面是需要定义一个json的,好,再运行看一下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_springboot_131

对路由做判断,防止用户通过手敲url访问管理页面:

现在还有个问题,就是虽说已经在登录菜单上已经根据登录状态进行显隐控制了,但是用户还是可以直接通过管理的路由地址来访问到,比如:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_vue3_132

所以接下来处理它。

1、路由中增加meta信息:

为了要处理需要登录的路由地址,这里需要在路由配置中增加一个meta信息,如下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_vue3_133

2、路由登录拦截:

接下来咱们则需要进行路由跳转的一个拦截处理,这块的写法也比较固定,写一次就明白了:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_spring_134

然后接下来就是要判断路由地址中有木有这个mate信息,如下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_springboot_135

而条件体里面的写法如下:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_redis_136

3、运行:

下面来运行看一下效果:

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_spring_137

成功进行路由的登录拦截了。

总结:

好了,花了很长的篇幅就将用户登录相关的给学习完了,还是收获很多的,比如密码的双层加层,登录的拦截等等,下次继续。





关注个人公众号,获得实时推送

Spring Boot&Vue3前后端分离实战wiki知识库系统<十三>--单点登录开发二_vue3_138



标签:wiki,10,登录,--,Spring,oss,process,com,image
From: https://blog.51cto.com/u_15456329/7510860

相关文章

  • Tomcat搭建文件下载服务
    1、安装tomcat2、安装完成后修改安装目录下/conf/server.xml文件在host的标签下加入<!--docBase属性:指定下载文件的目录,根据自己实际情况填写--><!--path属性:下载文件时浏览器输入的路径,根据自己实际情况填写--><ContextdocBase="D:/软件/操作系统相关"path="/download"re......
  • 数据库数据恢复-ORACLE数据库常见故障有哪些?oracle数据库出现这些故障能恢复数据吗?
    ORACLE数据库常见故障:1、ORACLE数据库无法启动或无法正常工作。2、ORACLE数据库ASM存储破坏。3、ORACLE数据库数据文件丢失。4、ORACLE数据库数据文件部分损坏。5、ORACLE数据库DUMP文件损坏。 ORACLE数据库数据恢复可能性分析:1、ORACLE数据库无法启动或无法正常工作:突然出......
  • 极验率先推出一键认证安全版,供客户自主免费升级,规避日常运营中的风险盲区
    2017年6月1日,互联网服务开始响应《中华人民共和国网络安全法》的要求实施账号实名认证。由此,手机号码成为网络世界最主要的“身份证”,也让本机号码一键认证成为可能。其中,极验是最早的直连三大运营商的五家供应商之一,早在2017年就正式对外提供一键认证接口。一键认证于2020年进入普......
  • 【Vue】el & data的这些细节你知道吗
    hello,我是小索奇,精心制作的Vue教程持续更新哈,花费了大量的时间和精力,总结拓展了很多疑难点,想要学习&巩固&避坑就一起学习叭~el与data的两种写法el共有2种写法el表达式主要用来在模板中展示数据,它可以输出简单的变量值,也可以调用方法。语法是${表达式}创建Vue实例对象的时候配......
  • 应用场域的深度融合与创新构想
    近年来,随着人工智能技术的迅速发展,自然语言处理技术也取得了显著的进步。其中,ChatGPT作为一种高效的自然语言处理模型,已经在许多领域得到了广泛的应用。本文主要围绕ChatGPT的调研分析以及其与应用场域的结合构想展开讨论。一、ChatGPT调研分析ChatGPT是一种基于深度学习的自然语言......
  • eNSP和HCL Cloud兼容性的问题,你都会解决吗?
    问题:eNSP或HCL无法启动不兼容的原因:eNSP支持VirtualBox是5.2.44;HCL支持的VirtualBox版本是6.0.14解决方案:注册表欺骗再进行重新安装前先把之前的都卸载掉:eNSP、VirtualBox、HCL等1、先安装VirtualBox5.2.44版本VirtualBox往期版本的下载地址:Download_Old_Builds_5_2–Oracle......
  • 创新性与自主性的融合
    随着人工智能(AI)技术的快速发展,各种新的AI技术和应用层出不穷。其中,AIGC和生成式AI是两个备受关注且在很多情况下被混淆的概念。本文将探讨这两个术语的区别和联系,帮助读者更好地理解它们。首先,让我们对AIGC和生成式AI进行定义。AIGC,全称人工智能生成内容(ArtificialIntelligenceGe......
  • 解密Spring Boot:JPA vs. MyBatis,哪个更适合你的项目?
    Hello大家好,我是小米!今天我要和大家聊聊一个在Java开发中经常会遇到的问题,那就是如何在SpringBoot项目中区分何时该使用JPA,何时该使用MyBatis。这个问题一直困扰着很多开发者,但其实只要理清一些基本概念和场景,就能轻松解决。废话不多说,让我们一起深入探讨吧!了解JPA和MyBatis首先,让......
  • 未来社交媒体的变革者
    近日,Meta宣布了其认可的七大社交媒体趋势,这些趋势代表了未来社交媒体发展的核心方向。这些趋势中,生成式AI、AR/VR营销等引人注目的技术入选,预示着我们即将迎来全新的社交媒体时代。一、生成式AI:像人一样理解并回应近年来,生成式AI在社交媒体中迅速发展,并将在未来几年继续保持强劲增......
  • AI编程助手你确定不想要?代码速度直接起飞!
    ❝在AI的冲击下,涌现了各种各样的优秀软件和插件,本篇就分享一个AI写代码工具。❞无论你是什么语言都可以使用呦!优缺点用了也一段时间了,虽然基本上都是写前端,但是对Vue、React、原生JS都比较友好,其他语言也是如此!优点非常的智能,有时候能预感到我接下来要写什么,亦或者对变量的提示,反正......