亲测有效!SpringBoot项目采用JWT登录认证与保持,并解决跨域问题

目录

  • 一、配置JWT详细教程
  • 二、加了JWT后出现的跨域问题解析
  • 三、'Bearer '问题(可能是它引起的令牌失效!)


一、配置JWT详细教程

系统环境:

  • SpringBoot后端项目,引入了Security依赖,采用了配置Security类来解决跨域问题
  • 前端采用VUE框架以及axios方法

参考教程:《实践:前后端分离实现JWT登录验证,包括前、后端配置》一步步跟着做就可以了。

个人理解:
① Token的生成

  1. 前端:用户输入账号、密码,点击登录,前端请求发送到后端
  2. 后端:接收前端请求,验证账号、密码,验证成功,根据账号信息生成Token令牌,并将Token令牌返回给前端
  3. 前端:接收Token令牌,存储在localStorage里

② 登录状态保持与权限问题

  1. 前端:将localStorage里的Token令牌配置到axios的请求头中,每次axios发送请求时请求头中都会携带Token令牌
  2. 后端:设置拦截器,拦截前端请求,并验证前端请求的请求头中的Token令牌,验证通过则继续执行请求,验证失败则取消该请求

二、加了JWT后出现的跨域问题解析

可能原因1:
SpringBoot加了拦截器后出现的跨域问题解析
SpringBoot使用Jwt处理跨域认证问题
可能原因2:
这个问题可能是由于前端发送请求时没有将token放入请求的header中导致的。在使用JWT实现认证时,需要将生成的token存储到前端,并在每次向后端发送请求时将token放入请求header中,这样后端才能识别该用户是否已登录以及是否有权限访问该接口。
你可以在前端代码的main.js中添加一个拦截器,在请求被发送出去之前,将存储在localstorage中的token添加到请求header中,例如:

axios.interceptors.request.use(
  (config) => {
    const token = localStorage.getItem('token');
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  (error) => Promise.reject(error)
);

这段代码会在每次请求前检查localstorage中是否存在token,并将其添加到请求的header中。这样,当后端接收到请求时,就可以从header中获取token并进行认证和授权操作了。
注意:为了避免XSS攻击,不要直接将token存储在localstorage中,可以考虑使用sessionStorage或者cookie等更加安全的存储方式。
这里是将《实践:前后端分离实现JWT登录验证,包括前、后端配置》里前端main.js的拦截器代码重写了一下,我是这个问题。

三、'Bearer '问题(可能是它引起的令牌失效!)

前端配置JWT时,在将Token配置到axios请求头时会在main.js用到如下代码:

// 请求拦截
axios.interceptors.request.use(
    (config) => {
        const token = localStorage.getItem('token');
        if (token) {
            config.headers.Authorization = "Bearer "+token;
        }
        return config;
    },
    (error) => Promise.reject(error)
);

其中 config.headers.Authorization = "Bearer "+token; 专门添加了’Bearer ',添加’Bearer '的原因如下:

  • Bearer是指OAuth 2.0协议中的一种认证方式。在使用OAuth 2.0进行API认证时,需要通过Access Token来访问受保护的资源。Bearer就是用来表明此处所使用的Access Token类型。
  • 添加Bearer前缀是为了告诉服务器,我们正在使用Bearer令牌进行身份验证。服务器收到带有Bearer令牌的请求后,会解析出令牌并对其进行验证。如果验证通过,则允许请求对受保护的资源进行操作。
  • 因此,在config.headers.Authorization = "Bearer "+token;中,Bearer是指定了使用的Access Token的类型,而token则是具体的Access Token值。

所以,后端解析请求头中的Token时,得到的是带有Bearer 的Token,然而验证Token、解析Token都需要“干净”的Token,即没有Bearer 的Token,所以如下需要把Bearer 去除:
①验证Token方法

public static Map<String, Claim> verifyToken(String token)throws Exception{
        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
        DecodedJWT jwt = null;
        // 删除前7个字符:将Bearer 删除得到“干净”的token
        token = token.substring(7);
        try {
            jwt = verifier.verify(token);
        }catch (Exception e){
            throw new RuntimeException("凭证失效");
        }
        return jwt.getClaims();
    }

解析Token方法

@Override
    public List<UserInfoDto> getUserInfo(HttpServletRequest request) {
        // 获取请求头中的Token值
        String authHeader = request.getHeader("Authorization");
        String token = "";
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
        	// 去除‘Bearer ’
            token = authHeader.substring(7);
        }
        // 获取Token中用户email
        String email = JwtUtil.parseToken(token).get("email").asString();
        UserInfoDto dto = new UserInfoDto();
        dto.setEmail(email);
        // 查询用户信息
        List<UserInfoDto> ressultList = getUserInfo_private(dto);
        return ressultList;
    }

你可能感兴趣的:(SpringBoot,spring,boot,vue.js,java)