• 使用jjwt进行微服务鉴权


    一、注册签发token和登录鉴权

    1.添加依赖

            <dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
                <version>0.6.0</version>
            </dependency>

    2.在common工程新建JwtUtil类

    @ConfigurationProperties("jwt.config") //读取appplication.yml内的该节点
    public class JwtUtil {
    
        private String key ;
    
        private long ttl ;//一个小时
    
        public String getKey() {
            return key;
        }
    
        public void setKey(String key) {
            this.key = key;
        }
    
        public long getTtl() {
            return ttl;
        }
    
        public void setTtl(long ttl) {
            this.ttl = ttl;
        }
    
        /**
         * 生成JWT
         *
         * @param id
         * @param subject
         * @return
         */
        public String createJWT(String id, String subject, String roles) {
            long nowMillis = System.currentTimeMillis();
            Date now = new Date(nowMillis);
            JwtBuilder builder = Jwts.builder().setId(id)
                    .setSubject(subject)
                    .setIssuedAt(now)
                    .signWith(SignatureAlgorithm.HS256, key).claim("roles", roles);
            if (ttl > 0) {
                builder.setExpiration( new Date( nowMillis + ttl));
            }
            return builder.compact();
        }
    
        /**
         * 解析JWT
         * @param jwtStr
         * @return
         */
        public Claims parseJWT(String jwtStr){
            return  Jwts.parser()
                    .setSigningKey(key)
                    .parseClaimsJws(jwtStr)
                    .getBody();
        }
    
    }

    3.在application.yml配置密钥和过期时间

    jwt:
      config:
        key: bofeng
        ttl: 3600000

    4.在启动类将JwtUtil加入spring容器

        @Bean
        public JwtUtil jwtUtil() {
            return new JwtUtil();
        }

    5.在登录方法中生成token

        @Autowired
        private JwtUtil jwtUtil;
      
       @PostMappng("/login")
    public Result login(@RequestBody User user) { User customerUser = userService.findByMobileAndPassword(user.getMobile(), user.getPassword()); if (customerUser != null) { String token = jwtUtil.createJWT(user.getId(), user.getMobile(), "user"); //三个参数分别为id,名称,角色 Map map = new HashMap(); map.put("token", token); map.put("role", "user"); return new Result(true, StatusCode.OK, "登录成功", map); } return new Result(false, StatusCode.LOGINERROR, "用户名或密码错误"); }

    6.创建过滤器提取请求头里的token

    @Component
    public class JwtFilter implements HandlerInterceptor {
        @Autowired
        private JwtUtil jwtUtil;
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("经过过滤器");
            String token = (String) request.getHeader("Authorization");
            if (token != null) {
                try {
                    Claims claims = jwtUtil.parseJWT(token);
                    String roles = (String) claims.get("roles");
                    if ("admin".equals(roles)) {
                        request.setAttribute("token_admin", token);
                    } else if ("user".equals(roles)) {
                        request.setAttribute("token_user", token);
                    }
                } catch (Exception e) {
                    throw new RuntimeException("令牌不正确");
                }
            }
            return true;
        }
    }

    7.创建过滤器配置类

    @Configuration
    public class InterceptorConfig extends WebMvcConfigurationSupport {
        @Autowired
        private JwtFilter jwtFilter;
    
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(jwtFilter)        //配置过滤器
                    .addPathPatterns("/**")          //配置拦截路径
                    .excludePathPatterns("/**/login");   //排除拦截路径
        }
    }

    二、jjwt详细使用规则

    1.生成token

    JwtBuilder builder= Jwts.builder()
        .setId("888")     .setSubject("小白")     .setIssuedAt(new Date())
        .setExpiration(new Date(exp));
        .claim("roles","admin")
        .claim("logo","logo.png");
        .signWith(SignatureAlgorithm.HS256,
    "bofeng");

    signWith用于设置加密算法和签名秘钥

    setIssuedAt用于设置签发时间,setExpiration设置token过期时间,.claim用于自定义claims。这三项都是可选设置

    2.解析token

    Claims claims = Jwts.parser().setSigningKey("bofeng").parseClaimsJws(token).getBody(
    );
    System.out.println("id:"+claims.getId());
    System.out.println("subject:"+claims.getSubject());
    System.out.println("roles:"+claims.get("roles"));
    System.out.println("logo:"+claims.get("logo"));
    SimpleDateFormat sdf=new SimpleDateFormat("yyyy‐MM‐dd hh:mm:ss");
    System.out.println("签发时间:"+sdf.format(claims.getIssuedAt()));
    System.out.println("过期时间:"+sdf.format(claims.getExpiration()));
    System.out.println("当前时间:"+sdf.format(new Date()) );

    setSigningKey用于设置密钥,parseClaimsJws用于设置要解析的token

  • 相关阅读:
    设计模式--总结
    设计模式--行为型模式--解释器模式
    设计模式--行为型模式--备忘录模式
    设计模式--行为型模式--访问者模式(Visitor模式)
    设计模式--行为型模式--迭代器模式
    设计模式--行为型模式--中介者模式
    js常用方法集合
    CSS 每隔4行显示不同样式的表格
    常用正则验证
    wIndow 强制关闭被占用的端口
  • 原文地址:https://www.cnblogs.com/naixin007/p/10688441.html
Copyright © 2020-2023  润新知