我是如何做到开源系统中的检测到未登录自动跳转到登录页面的?

3549 篇文章 124 订阅
文章介绍了在前后端分离的项目中如何实现登录权限控制,主要涉及JWT令牌的生成与验证。当用户登录成功后,后端返回JWTtoken,前端将其存储在cookie中。在后续的请求中,通过axios拦截器添加token到请求头。如果检测到无权限(如token失效),前端会自动重定向到登录页面。提供了相关代码示例和仓库链接以供参考。
摘要由CSDN通过智能技术生成

实现未登录跳转到登录界面的方法有很多,例如后端框架使用springsecurity来实现安全框架

java复制代码  @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 表单认证
        http.formLogin()
        .successForwardUrl("/welcome") //登录成功后,跳转到指定请求(此处是 post 请求)
        .failureForwardUrl("/loginFail")//登录失败
        .loginPage("/login.html");

但是,咱们的系统是前后端分离的,实现上面的逻辑很复杂,所以结合这个项目,我觉得自己开发一套登录权限认证功能。 首先我们要知道前后端分离一般使用json和浏览器cookie来交换数据,所以这里我们需要前后端一起来配合完成这个功能。

第一步,我们在JWTAuthenticationFilter类中定义登录成功的方法

java复制代码 // 成功验证后调用的方法
    // 如果验证成功,就生成token并返回
    @Override
    protected void successfulAuthentication(HttpServletRequest request,
                                            HttpServletResponse response,
                                            FilterChain chain,
                                            Authentication authResult) {

        JwtUser jwtUser = (JwtUser) authResult.getPrincipal();
        System.out.println("jwtUser:" + jwtUser.toString());
        boolean isRemember = rememberMe.get() == 1;

        String role = "";
        Collection<? extends GrantedAuthority> authorities = jwtUser.getAuthorities();
        for (GrantedAuthority authority : authorities) {
            role = authority.getAuthority();
        }

        String token = JwtTokenUtils.createToken(jwtUser.getUsername(), role, isRemember);
        // 返回创建成功的token
        // 但是这里创建的token只是单纯的token
        // 按照jwt的规定,最后请求的时候应该是 `Bearer token`
        String authToken = JwtTokenUtils.TOKEN_PREFIX + token;
        String result = JSONObject.toJSONString(ResponseUtils.success(authToken));
        try {
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(result);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

这里的作用就是我们登录成功后会返回jwt产生的token值

第二步,我们在前端登录成功的时候将这个值存储在cookie中去

java复制代码import Cookies from 'js-cookie'

const TokenKey = 'Authorization'

export function getToken() {
  return Cookies.get(TokenKey)
}

export function setToken(token) {
  return Cookies.set(TokenKey, token)
}

export function removeToken() {
  return Cookies.remove(TokenKey)
}

这个是auth.js用来利用js-cookie来操作浏览器token的

java复制代码methods: {
    login() {
      if (this.loginForm.username === "" || this.loginForm.password === "") {
        alert("账号或密码不能为空");
      } else {
        loginvalidate(this.loginForm)
            .then((res) => {
              console.log("rerer", res)
              if (res.code === "0000") {
                setToken(res.data);
                this.$router.push("/homePage")
              } else {
                alert("账号或密码错误");
              }
            })

            .catch((error) => {
              alert("系统出现错误");
              console.log(error);
            });
      }
    },

setToken方法就能将后端返回回来的token存储到cookie中 这里不了解的可以去这篇专栏的上两篇去了解一下

第三步,这步我称为拦截器

在发送和接收后端返回的数据的时候进行拦截

java复制代码import axios from 'axios'
import { getToken } from './auth'
import Router from "vue-router";


//创建axios实例
const service = axios.create({
    baseURL: '/api',
    timeout: 10000
})
// request interceptor
service.interceptors.request.use(
    config => {
        config.headers.Authorization = getToken()
        // do something before request is sent
        return config
    },
    error => {
        // do something with request error
        console.log(error) // for debug
        return Promise.reject(error)
    }
)

// response interceptor
service.interceptors.response.use(
    response => {

        const res = response.data
        console.log("res",response);
        if (res.code === "0401"){
            new Router().push("/");
            location.reload();
        }
        return res;
    },
    error => {
        console.log('err' + error) // for debug
    }
)
export default service

这里的意思(service.interceptors.request.use)就是在每个请求头中加入配置 这个意思(service.interceptors.response.use)就是在每个返回信息中中修改配置 这里有个大坑:就是config.headers.Authorization = getToken()这里,一点要每次都调用方法一下,不能够这样写:

java复制代码let AUTH_TOKEN = getToken()
config.headers.Authorization = AUTH_TOKEN

这个真的是坑死我了,花费了我一天时间去找这个bug(每次登录的时候都会拿不到cookie)

java复制代码   if (res.code === "0401"){
            new Router().push("/");
            location.reload();
        }

这里的意思就是当我检测返回的数据里面的code值为0401的时候(自己后端定义的)就会push到登录页面 这样,我们每次在token删除或者token失效的时候返回后端的接口,然后后端就会发现没有权限,就会返回0401转态码给前端,前端接受处理之后就会push到登录页面,这样就实现了检测到未登录自动跳转到登录页面的功能啦! 更多的代码我开了个仓库供大家参考

前端仓库地址:

gitee.com/programmer-…

后端仓库地址:

gitee.com/programmer-…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值