JWT 鉴权方式是不同于传统session 得一种方式,方便实现跨域和分布式鉴权。
JWT架构图
maven依赖:
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
关于JWT 得简单使用方法网上已经很多了,我这里不再过多介绍,可以参考
http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html
他得源码也很简单易懂:
从源码中能能很清楚得看出JWT token值得组成结构。 基于他得结构我们在使用它得时候不能把重要得信息放入JWT中,因为他没有加密:
String base = "eyJqdGkiOiIxIiwic3ViIjoieGlhbmdqaW4iLCJpc3MiOiJ1c2VyIiwiaWF0IjoxNTY2OTczNDA5LCJleHAiOjE1NjY5NzQ0MDl9";
Base64UrlCodec d = new Base64UrlCodec();
byte [] s = d.decode(base);
System.err.println(new String(s,"UTF-8"));
如上所示,我们能很容易就解读JWT中得内容。
如果我们确实有这方面得需要可以考虑对重要内容加密后在使用JWT
JWT 与SpringMVC 配合使用
我们需要一个拦截器,方便我们在其他用户登录时拦截请求并检查token
在DispatcherServlet的配置文件中的<beans>标签内加入拦截器配置声明
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="你的包名.你的拦截器"></bean>
</mvc:interceptor>
</mvc:interceptors>
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
//实现Spring拦截器接口 HandlerInterceptor
public class HeaderTokenInterceptor implements HandlerInterceptor {
@Autowired
//该注解使Spring自动为bean设置get与set。
JWTUtil jwtUtil;
//JWT工具类
//第一个函数preHandle是预处理函数,比如我们用于拦截登录时,它是第一个工作的。
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler) throws Exception {
//System.out.println("进入preHandle方法");
String headerToken=httpServletRequest.getHeader("token");
//获取我们请求头中的token验证字符
String tokenStr=httpServletRequest.getParameter("token");
//getParameter的变量是放在我们请求附带的对象中的字符串,例如post方法中附带的account变量等。
if(!httpServletRequest.getRequestURI().contains("login")){
//检测当前页面,我们设置当页面不是登录页面时对其进行拦截
//具体方法就是检测URL中有没有login字符串
if(headerToken==null && tokenStr==null){
httpServletResponse.sendRedirect("login.do");
//如果token不存在的话,我们将页面重定向到login.do,也就是登录页面去。
return false;
//当返回值是false的时候,表示拦截器不会进行处理了,我们调用response来进行响应。
}
if(tokenStr!=null){
headerToken=tokenStr;
//进行token同步,后面我们会对token做验证与更新
}
try {
headerToken=jwtUtil.updateToken(headerToken);
//对token进行更新与验证
}catch(Exception e) {
httpServletResponse.sendRedirect("login.do");
//当token验证出现异常返回到登录页面
return false;
}
System.out.println("real token:=="+headerToken);
System.out.println("real Cookie:=="+httpServletRequest.getHeader("Cookie"));
}
httpServletResponse.setHeader("token",headerToken);
//将token加入返回页面的header
return true;
//当返回true表示第一个阶段结束,随后会执行postHandle和afterCompletion
}
//当请求到达Controller但是未渲染View时进行处理
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
//相当于最后的回调函数
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
}
这段代码是拿得网上得,只是表达这个意思,具体怎么做需要根据各自得具体业务来处理。