使用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

posted on 2019-04-11 11:11  bofeng  阅读(1156)  评论(0编辑  收藏  举报