[业务流程]JWT实现单点登录(SpringBoot + Vue +axious)

JWT实现单点登录(SpringBoot + Vue +axious)

准备阶段:

**登录所需对象**
admin{
"username":"",  //作为Token
"password":"",  //作为签名
"nicakname":"",
"avatar":"",
}

开始阶段

1.导包

  
  <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.10.3</version>
        </dependency>

2.创建一个TokenUtils(放在util包下)

public class TokenUtils {
    public static String getToken(admin admin){
        String token="";
        token= JWT.create().withAudience(admin.getUsername()) // 将 username 保存到 token 里面
                .withExpiresAt(DateUtil.offsetHour(new Date(),1)) //1小时后token过期(DateUtil是hutool包下的)
                .sign(Algorithm.HMAC256(admin.getPassword())); // 以 password 作为 oken的密钥,默认用HMAC256加密
        return token;
    }
}

3.在admin的相应controller下创建login方法

@PostMapping("/login")
    //  1.接收前端传来的登录前Json对象
    public Result login(@RequestBody admin admin){
        String username = admin.getUsername();
        String password = admin.getPassword();
        
        
        if (username == "" || password == "") {
            throw new ServiceException(Constants.CODE_401,"没有输入");
        }
​
        //  2.进行登录操作,验证数据库是否有该对象,并得到登录后对象
        com.pinkman.management.entity.admin loginAdmin = adminService.login(admin);
​
        //  3.将Token设置进登录后对象
        String token = TokenUtils.getToken(loginAdmin);
        loginAdmin.setToken(token);
        //  4.返回给前端
        return new Result(adminService.login(admin) == null?Constants.CODE_200:Constants.CODE_401,"成功",loginAdmin);
    }

 

 

前端阶段

1.前端登录方法

login() {
      var user = {
        username: this.username,
        password: this.password,
      };
​
      this.request
        .post("http://localhost:8888/admin/login", user)
        .then((res) => {
          console.log(res);
          if (res.code == "401") {
           
​
            localStorage.setItem("user", JSON.stringify(res.data));
      
            //储存Token信息
            localStorage.setItem("token", res.data.token);
​
            this.$router.push("/");
          } else {
            this.$message.error("用户名或密码错误");
          }
        });

tips:前端传给后端时候,正确token:xxx.yyy.zzz,不正确token:"xxx.yyy.zzz"

成功写入本地存储:

2.在前端Vue集成的项目中对axious进行配置

import axios from 'axios'
// request 拦截器
// 可以自请求发送前对请求做一些处理
// 比如统一加token,对请求参数统一加密
request.interceptors.request.use(config => {
    config.headers['Content-Type'] = 'application/json;charset=utf-8';
    //  在这里拿到Token信息并且写入到请求的头中去
    config.headers['token'] = localStorage.getItem("token");
    return config
}, error => {
    return Promise.reject(error)
});

Token成功写入请求头

 

验证阶段

1.前端发送任意带token的请求给后端

2.在后端的config包下的interceptor包下配置相应拦截器(配置校验规则)

@Component
public class JwtHandlerInterceptor implements org.springframework.web.servlet.HandlerInterceptor {
​
    @Autowired
    private adminService adminService;
​
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("token");
        //  0.如果不是映射方法,则直接通过
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
​
        //  1.先通过token获取相应的用户名
        if (StringUtils.isBlank(token)) {
            throw new ServiceException(Constants.CODE_401,"无Token,请先登录");
        }
        String username;
        try{
            username = JWT.decode(token).getAudience().get(0);
        }catch (JWTDecodeException j){
            throw new ServiceException(Constants.CODE_401,"Token验证失败");
        }
​
​
​
        //  2.根据获取到的用户名查询数据库是否存在该用户
        admin admin = adminService.getAdminByName(username);
        if (admin == null) {
            throw new ServiceException(Constants.CODE_401,"用户不存在");
        }
        //  用户密码加签 验证Token
        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(admin.getPassword())).build();
​
​
        //  3.若存在,则对签名进行核验
        try {
​
            jwtVerifier.verify(token);  //  验证token
        } catch (JWTVerificationException e) {
            e.printStackTrace();
        }
        System.out.println("成功验证");
        //  4.核验完成则返回true
        return true;
​
    }
}

3.在后端的config包下创建拦截器JwtInterceptorConfig配置(让服务器知道拦截器的存在)

//  1.配置注解
@Configuration
//  2.实现WebMvcConfigurer接口
public class InterceptorConfig implements WebMvcConfigurer {
​
    
    @Bean
    public JwtHandlerInterceptor getJwtHandlerInterceptor(){
        return new JwtHandlerInterceptor();
    }
    //  3.重写方法,将jwt拦截器注册进拦截器注册中心(让web应用上下文知道拦截器的存在)
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(getJwtHandlerInterceptor())
                .addPathPatterns("/**")    //   拦截所有请求,通过判断token是否合法来决定是否登录
                .excludePathPatterns("/admin/login");     // 排除部分,如,登录请求(必须排除),导入请求,导出请求
    }
}

tips:拦截器在初始化时候记得放进spring容器中

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值