重温JWT/Token

=start====================本篇用springboot来搭建登录之JWT
1.添加依赖
正常的springboot依赖
JWT依赖

com.auth0
java-jwt
3.4.0

2.新建一个自定义注解配合JWT使用
@Target(value = {ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Login {
boolean mustlogin() default true;
}
3. 生成token令牌 设置有效期为一个小时
public String generateToken(UserInfo userInfo) {
return JWT.create().withIssuedAt(new Date()).withExpiresAt(new Date(System.currentTimeMillis() + 1000 * 60 * 60))
.withSubject(userInfo.getId() == null ? null : userInfo.getId().toString())
.withIssuer(“root/admin”)
.withClaim(“username”, userInfo.getName())
.sign(getTokenByKey());
}

public Algorithm getTokenByKey() {
    return Algorithm.HMAC256("Zhang147927ErMeng");//服务器生成/解析token的密匙切记不可丢失
}

4.解析token的方法
public UserInfo verifyByToken(String token) {
if (token == null || “”.equals(token)) {
return null;
}
DecodedJWT decodedJWT = null;
try {
JWTVerifier jwtVerifier = JWT.require(getTokenByKey()).build();
decodedJWT = jwtVerifier.verify(token);
Date expiresDate = decodedJWT.getExpiresAt();
if (expiresDate != null && expiresDate.after(new Date())) {
String userid = decodedJWT.getSubject();
if (userid != null && !"".equals(userid)) {
return userInfoJPA.getOne(Long.parseLong(userid));
} else {
return null;
}
}
} catch (Exception e) {
System.out.println(“校验token异常!”);
}
return null;
}
5.
编写拦截器

public class InterfaceConfig implements HandlerInterceptor {
@Autowired
public UserInfoService userInfoService;

@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
    //不是方法级别的直接跳过
    if (!(o instanceof HandlerMethod)) {
        return true;
    }
    HandlerMethod handlerMethod = (HandlerMethod) o;
    Method method = handlerMethod.getMethod();
    Login login = method.getAnnotation(Login.class);
    //如果有注解说明是登录接口,直接放过
    if (login != null) {
        return true;
    }
    String token = httpServletRequest.getHeader("token");
    if (null == token || token.equals("") || token.equals("undefind")) {
        Cookie cookie = WebUtils.getCookie(httpServletRequest, "ByToken");
        if (cookie == null) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("status", httpServletResponse.SC_UNAUTHORIZED);
            jsonObject.put("flag", false);
            jsonObject.put("message", "Not find by token!");
            httpServletResponse.getWriter().write(jsonObject.toJSONString());
            httpServletResponse.getWriter().close();
            return false;
        }
        token = cookie.getValue();
        if (null == token || token.equals("") || token.equals("undefind")) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("status", httpServletResponse.SC_UNAUTHORIZED);
            jsonObject.put("flag", false);
            jsonObject.put("message", "Not find by token!");
            httpServletResponse.getWriter().write(jsonObject.toJSONString());
            httpServletResponse.getWriter().close();
            return false;
        }
    }
    UserInfo userInfo = userInfoService.verifyByToken(token);
    //UserInfo userInfo = new UserInfoService().verifyByToken(token);
    if (userInfo != null) {
        UserInfoContent.setUserInfoContent(userInfo);
        return true;
    }
    JSONObject jsonObject = new JSONObject();
    jsonObject.put("status", httpServletResponse.SC_FORBIDDEN);
    jsonObject.put("flag", false);
    jsonObject.put("message", "The token is bad!");
    httpServletResponse.getWriter().write(jsonObject.toJSONString());
    httpServletResponse.getWriter().close();
    return false;
}

@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

}

@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    UserInfoContent.clearUserInfoContent();
}

}
6。使拦截器生效 顺便把跨域请求的也配置一下
@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {
@Bean
public InterfaceConfig interfaceConfig() {
return new InterfaceConfig();
}

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(interfaceConfig()).addPathPatterns("/**");
    super.addInterceptors(registry);
}

@Override//跨域配置
public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/**")
            .allowedMethods("*")
            .allowedOrigins("*")
            .allowedHeaders("*");
    super.addCorsMappings(registry);
}

}
7.自己研究的是否发现一个问题,每次登陆的时候判断完token之后再调用接口的时候如果服务器想知道用户是谁怎么办。
自己想到了这样一个方法 在每次调用接口的时候 在拦截器里把用户信息放到一个线程的变量里面 这样在其他接口就可以直接调用用户信息
public abstract class UserInfoContent {
private static final ThreadLocal userLocal = new ThreadLocal<>();

	    public static void setUserInfoContent(UserInfo userInfo) {
	        userLocal.set(userInfo);
	    }
	
	    public static UserInfo getUserInfoContent() {
	        return userLocal.get();
	    }
	
	    public static void clearUserInfoContent() {
	        userLocal.set(null);
	        userLocal.remove();
	    }
  1. controller编写登录接口 有@Login注解就不会判断token
    @Login
    @RequestMapping("/login")
    @ResponseBody
    public Result test(String account, String password) {
    UserInfo userInfo = userInfoService.findUserInfo(account, password);
    if (userInfo == null) {
    return new Result(false, “the password or account is error !”);
    }
    //String token = userInfoService.generateToken(userInfo);*/
    //Long count = userInfoJPA.finduser(account, password);
    JSONObject jsonObject = new JSONObject();
    jsonObject.put(“id”, userInfo.getId());
    jsonObject.put(“name”, userInfo.getName());
    jsonObject.put(“account”, userInfo.getAccount());
    jsonObject.put(“token”, userInfoService.generateToken(userInfo));
    return new Result(true, “success”, jsonObject);
    }
    9.编写一个接口
    这个接口没有@Login注解说明需要token验证
    @RequestMapping("/testBytoken")
    @ResponseBody
    public String test1() {
    List list = userInfoJPA.findAll();
    System.out.printf(list.toString());
    return list.toString();
    }
    ==========================================================
    以上就是一些简单的配置和使用的过程 小白努力学习中
    ======end=
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值