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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM