Spring Boot整合JWT进行权限认证

  1. 介绍一下JWT的组成

第一部分为头部(header),第二部分我们称其为载荷(payload),第三部分是签证(signature)。【中间用 . 分隔】

一个标准的JWT生成的token格式如下:Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOjUwMCwicmlkIjowLCJpYXQiOjE2MjYzOTgwNDMsImV4cCI6MTYyNjQ4NDQ0M30.ojaiFvsGQew4SbbTakvwO2qv7TAWNgWk6GyvmIRdYV8
2. 话不多说,直接上项目截图
Spring Boot整合JWT进行权限认证_第1张图片
3. 首先导入JWT依赖(POM文件)

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

4.写一个工具类JwtUtil,用来生成token

private static String SIGN="!QQW#ERP";//这个是密钥,千万不要泄露,可以自己随意设置
    /**
     * 生成token  header.payload.sign
     */
    public static String getToken(Map<String,String> map){
        //设置令牌过期时间 7天
        Calendar instance=Calendar.getInstance();
        instance.add(Calendar.DATE,7);
        //创建jwt builder
        JWTCreator.Builder builder=JWT.create();
        //payload
        map.forEach((k,v)->{
            builder.withClaim(k,v);
        });
        String token = builder.withExpiresAt(instance.getTime())
                .sign(Algorithm.HMAC256(SIGN));
        return token;
    }
    /**
     * token验证 合法性
     */
    public static void verify(String token){
        JWT.require(Algorithm.HMAC256(SIGN)).build().verify(token);
    }
    /**
     * 获取token信息方法
     */
    public static DecodedJWT getTokenInfo(String token){
        DecodedJWT verify = JWT.require(Algorithm.HMAC256(SIGN)).build().verify(token);
        return verify;
    }
    /**
     * 获取key字段的值
     */
    public static String getInfoByToken(String token, String key) {
        //String value = getTokenInfo(token).getClaim(key).toString();
        写法相同
        String value = getTokenInfo(token).getClaims().get(key).asString();
        value = value.replace("\"", "").replace("\"", "");
        return value;
    }
    /**
     * 获取当前用户id
     *
     * @return
     */
    public static String getId() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String token = request.getHeader("token");
        DecodedJWT verify = JWT.require(Algorithm.HMAC256(SIGN)).build().verify(token);
        String id = verify.getClaims().get("id").asString();
        //String id = verify.getClaim("id").toString();
        return id;
    }
 }
  1. 写一个异常处理JWTInterceptor

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Map<String,Object> map=new HashMap<>();
        //获取请求头中的令牌
        String token = request.getHeader("token");
        try{
            JwtUtil.getTokenInfo(token);
            return true;
        }catch (SignatureVerificationException e){
            e.printStackTrace();
            map.put("msg","无效签名");
        }catch (TokenExpiredException e){
            e.printStackTrace();
            map.put("msg","token过期");
        }catch (AlgorithmMismatchException e){
            e.printStackTrace();
            map.put("msg","token算法不一致");
        }catch (Exception e){
            e.printStackTrace();
            map.put("msg","token无效");
        }
        map.put("state",false);
        String json = new ObjectMapper().writeValueAsString(map);
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().println(json);
        return false;
    }
  1. 写一个controller
@PostMapping("/login")
    public Map<String,Object> login(String userName,String password){
        Users users=new Users();//由于并没用到数据库,所以controller写死数据了
        users.setId("1001");
        users.setUserName(userName);
        users.setPassword(password);
        Map<String,Object> map=new HashMap<>();
        try{
            Map<String,String> payload=new HashMap<>();
            payload.put("id",users.getId());
            payload.put("userName",users.getUserName());
            payload.put("password",users.getPassword());
            String token = JwtUtil.getToken(payload);
            map.put("state",true);
            map.put("msg","认证成功");
            map.put("token",token);
        }catch (Exception e){
            map.put("stste",false);
            map.put("msg",e.getMessage());
        }
        return map;
    }
    @PostMapping("/test")
    public String test(){
        return  "拦截器不拦截我";
    }

7.创建一个实体类Users,由于并没用到数据库,所以controller写死数据了,自己写get()、set()方法

@Data
public class Users {
    private String id;
    private String userName;
    private String password;
}

8.这时候发现login和test都不进行token验证,login肯定不能进行验证,login用于生成token,但是进入test应该验证,所以创建拦截器InterceptorConfig

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new JWTInterceptor())
                .addPathPatterns("/**")     //拦截test
                .excludePathPatterns("/login");//排除登录,其他拦截
    }
}

结束

你可能感兴趣的:(有趣的功能实现,jwt,java)