一.什么是JSON Web Token:

  首先要明确的是JSON Web Token:是一个开放标准,这个标准定义了一种用于简洁,自包含的用于通信双方之间以JSON对象的形式安全传递信息的方法

  而我们在项目中使用的JWT Token就是通过一定规范生成token,常用于单体应用或者微服务应用下的登录校验解决方法

  那么问题来了,现有的登录校验方案,有Cookie和Seesion这些会话技术,那么为什么还需要JSON,Web Token呢,下面就这些问题来说明

二,JSON Web Token的组成

  JWT由三个部分组成:

    1.JWT头部 header

      -header部分用于描述JWT元数据的JSON对象,主要是用来哦描述签名部分所使用的算法

    2.JWT负载 payload

      -负载部分主要描述了加密对象的信息,如用户的id等等,也可以加写规范里面的东西,例如expire过期时间,iss签发者,sub面羡慕的用户等等

    3.JWT签名 signature

      -签名部分主要是讲前面的header部分和payload部分两部分进行加密,常用的是单向加密(也就是摘要算法,例如MD5,SHA等等,这些加解密算法,请阅读我另一篇博客)

      主要目的是为了防止别人那道token进行base解密后篡改token,用于保护数据的完整性

三,为什么要使用JWT,而不使用会话技术Cookie或者Seesion,

  

   在前后端分离的项目中,前端部署在Ngnix,后端代码部署在应用服务器Tomcat,Nginx和Tomcat分别部署在不同的服务器,前端浏览器的请求

通过Nginx代理转发到Tomcat所在的服务器中,并且前后端的交互也主要是通过ajax请求(例如,vue组件axios),在不设置跨域请求的前提下,Tomcat会将每一次的

ajax请求作为一个新的请求,生成一个新的Session,因此需要设置添加Cookie,

   Cookie是Session的载体,是Http请求头中的属性,Session在服务端生成并保存到服务端,服务端每次响应,会将Session传给浏览器,浏览器在下次请求的时候会以在Cookie中以SessionID:xxxxxx的形式带入到服务端做会话验证;

    这里就有几个缺点:

    1.Session的内存占用问题

    Session在服务端生成,并保存到服务端,以常见得场景注册登录的场景为例,用户登录成功之后,服务端生成Session用来保持会话,

很重要的一点就是,Session保存到内存中,当大量用户登录时,会造成大量内存被占用,造成服务器的压力;

    对比JWT Token 的认证方式,JWT同样也是在服务端生成响应给客户端,但是并不保存到服务端,减轻了服务器的内存压力,牺牲的仅仅是CPU在加解密时的计算性能,

相比内存大量被Seesion占用,牺牲CPU的计算能力来的更加划算;

    2.用户信息的问题:

    传统的Seesion和Cookie仅作为会话保持,并没有携带相关的用户信息,相反的JWT的payload负载部分,有携带用户的基本信息,可以做为简单的用户校验等等

四.JWT相关的代码以及工具类

工具类

/**
* jwt工具类
*/
public class JwtUtils { public static final String SUBJECT = "coolJWT"; public static final long EXPIRE = 1000*60*60*24*7; //过期时间,毫秒,一周 //秘钥
public static final String APPSECRET = "xd666"; /**
* 生成jwt
* @param user
* @return
*/
public static String geneJsonWebToken(User user){ if(user == null || user.getId() == null || user.getName() == null
|| user.getHeadImg()==null){
return null;
}
String token = Jwts.builder().setSubject(SUBJECT)
.claim("id",user.getId())
.claim("name",user.getName())
.claim("img",user.getHeadImg())
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis()+EXPIRE))
.signWith(SignatureAlgorithm.HS256,APPSECRET).compact(); return token;
}
/**
* 校验token
* @param token
* @return
*/
public static Claims checkJWT(String token ){ try{
final Claims claims = Jwts.parser().setSigningKey(APPSECRET).
parseClaimsJws(token).getBody();
return claims; }catch (Exception e){ }
return null; }
}

在拦截器中进行JWT的校验(注意:C端不适合做复杂的权限校验)

public class LoginIntercepter implements HandlerInterceptor {

    private static final Gson gson = new Gson();

    /**
* 进入controller之前进行拦截
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //token放在头Header信息中
String token = request.getHeader("token");
if(token == null ){
token = request.getParameter("token");
}
if(token != null ) {
//jWtUtils验证失败会返回null
Claims claims = JwtUtils.checkJWT(token);
if(claims !=null){
Integer userId = (Integer)claims.get("id");
String name = (String) claims.get("name"); request.setAttribute("user_id",userId);
request.setAttribute("name",name);
//验证成功
return true;
}
}
//验证失败
sendJsonMessage(response,JsonData.buildError("请登录"));
return false;
}
/**
* 响应数据给前端
* @param response
* @param obj
*/
public static void sendJsonMessage(HttpServletResponse response, Object obj) throws IOException {
response.setContentType("application/json; charset=utf-8");
PrintWriter writer = response.getWriter();
writer.print(gson.toJson(obj));
writer.close();
response.flushBuffer();
}
}

注册拦截器

/**
* 拦截器配置
*/
@Configuration
public class IntercepterConfig implements WebMvcConfigurer { @Override
public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginIntercepter()).addPathPatterns("/user/api/v1/*/**"); WebMvcConfigurer.super.addInterceptors(registry);
}
}

【Jwt】JSON Web Token的更多相关文章

  1. Go语言入门篇-jwt(json web token)权限验证

    一.token.cookie.session的区别 1.cookie Cookie总是保存在客户端中,按在客户端中的存储位置,可分为内存Cookie和硬盘Cookie. 内存Cookie由浏览器维护, ...

  2. JWT(JSON Web Token) 多网站的单点登录,放弃session

    多个网站之间的登录信息共享, 一种解决方案是基于cookie - session的登录认证方式,这种方式跨域比较复杂. 另一种替代方案是采用基于算法的认证方式, JWT(json web token) ...

  3. Laravel 5 中使用 JWT(Json Web Token) 实现基于API的用户认证

    在JavaScript前端技术大行其道的今天,我们通常只需在后台构建API提供给前端调用,并且后端仅仅设计为给前端移动App调用.用户认证是Web应用的重要组成部分,基于API的用户认证有两个最佳解决 ...

  4. JWT(Json web token)认证详解

    JWT(Json web token)认证详解 什么是JWT Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该to ...

  5. JWT(Json Web Token)初探与实践

    前言什么是JWT?为什么使用JWT?什么时候使用JWT?JWT的基本结构HeaderPayloadSignature将他们放在一起项目实践JWT后端前端关于安全性总结参考 协议标准:https://t ...

  6. 理解JWT(JSON Web Token)认证及python实践

    原文:https://segmentfault.com/a/1190000010312468?utm_source=tag-newest 几种常用的认证机制 HTTP Basic Auth HTTP ...

  7. (转)深入浅出JWT(JSON Web token)

    转载地址:https://www.cnblogs.com/mantoudev/p/8994341.html 参考地址:https://baijiahao.baidu.com/s?id=16080218 ...

  8. SpringBoot 2.x 使用 JWT(JSON Web Token)

    一.跨域认证遇到的问题 由于多终端的出现,很多的站点通过 web api restful 的形式对外提供服务,采用了前后端分离模式进行开发,因而在身份验证的方式上可能与传统的基于 cookie 的 S ...

  9. JWT(JSON Web Token) 多网站的单点登录,放弃session 转载https://www.cnblogs.com/lexiaofei/p/7409846.html

    多个网站之间的登录信息共享, 一种解决方案是基于cookie - session的登录认证方式,这种方式跨域比较复杂. 另一种替代方案是采用基于算法的认证方式, JWT(json web token) ...

随机推荐

  1. Snort + Barbyard2 + Snorby环境搭建

    1.环境 ubuntu-14.04.5 daq-2.0.7 Snort-2.9.15.1 Barbyard2 snorby Mysql Docker 2.架构 3.安装步骤 Ubuntu配置 如果是刚 ...

  2. 阅读源码,HashMap回顾

    目录 回顾 HashMap简介 类签名 常量 变量 构造方法 tableSizeFor方法 添加元素 putVal方法 获取元素 getNode方法 总结 本文一是总结前面两种集合,补充一些遗漏,再者 ...

  3. CVE-2017-12615 -Tomcat-任意写入文件

    漏洞分析参考 https://www.freebuf.com/vuls/148283.html 漏洞描述: 当 Tomcat运行在Windows操作系统时,且启用了HTTP PUT请求方法(例如,将 ...

  4. 开源大屏工具 DataGear 的使用

    记录一款好用的大屏工具,DataGear,官方标记为"开源免费的数据可视化分析平台". 其支持的数据集可以为SQL或HTTP API等,SQL支持MySQL等关系型数据库及Hive ...

  5. Python--入门接口测试(1)

    1. 什么是接口测试?为什么要做接口测试? 接口测试是测试系统组件间接口的一种测试.接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点.测试的重点是要检查数据的交换.传递和控制管理过 ...

  6. 如何安装jenkins并简单的使用

    如何安装jenkins并使用 一.jenkins 简介: Jenkins是基于Java开发的一种持续集成工具,用于监控持续重复的工作,功能包括 : 1.持续的软件版本发布/测试项目: 2.监控外部调用 ...

  7. 报错NameError: name ‘null’ is not defined的解决方法

    报错NameError: name 'null' is not defined的解决方法 eval()介绍 eval()函数十分强大,官方demo解释为:将字符串str当成有效的表达式来求值并返回计算 ...

  8. WPF 基础 - Binding 对数据的转换和校验

    1. Binding 对数据的转换和校验 Binding 中,有检验和转换关卡. 1.1 数据校验 源码: namespace System.Windows.Data { public class B ...

  9. ECMAScript 2016(ES7)新特性简介

    简介 自从ES6(ECMAScript 2015)在2015年发布以来,ECMAScript以每年一个版本的速度持续向前发展.到现在已经是ECMAScript 2020了. 每个版本都有一些新的特性, ...

  10. python多线程参考文章

    1. https://www.jianshu.com/p/c93e630d8089 2.https://www.runoob.com/python/python-multithreading.html ...