JWT简介:

JWT(JSON WEB TOKEN):JSON网络令牌,JWT是一个轻便的安全跨平台传输格式,定义了一个紧凑的自包含的方式在不同实体之间安全传输信息(JSON格式)。它是在Web环境下两个实体之间传输数据的一项标准。实际上传输的就是一个字符串。广义上讲JWT是一个标准的名称;狭义上JWT指的就是用来传递的那个token字符串

jwt特点:

  • JWT无需存储在服务器(不使用Session/Cookie),不占用服务器资源(也就是Stateless无状态的),也就不存在多服务器共享Session的问题
  • 使用简单,用户在登录成功拿到 Token后,一般访问需要权限的请求时,在Header附上Token即可。

JWT公司官网:   

  1. https://jwt.io/

jwt的token结构:

JWT的数据结构以及签发的过程
JWT由三部分构成:header(头部)、payload(载荷)和signature(签名)。

Header 头部信息:指定类型和算法
Payload 荷载信息:存放Claims声明信息
Signature 签名:把前两者对应的Json结构进行base64url编码之后的字符串拼接起来和密钥放一起加密后的签名
组成方式为: header.payload.signature

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJpc3MiOiLlvKDlvLoiLCJuYW1lIjoiNzg5IiwiZXhwIjoxNTI4MzY0MjU5LCJpYXQiOjE1MjgzNjMwNTl9.574koY-c9SqMNNzfvAWQuKEnimWeZAcoFQ5XudNWF3o

因为是拼接的所以base64很容易破解,所以建议在传输过程中采用ssl加密是最稳妥的,这样就不会被别人破解了你的荷载信息,

你该如何去理解JWT帮你做些什么?

  结合业务场景,首先前端登录 后端通过用户名与密码验证成功后,使用jwt生成 一个具备有效期的token令牌, 这个token里面存储着 token本身的结构,加上token的过期时间,和一个你自己定义的字符串类似于加密 签名所用的盐,这个盐只有你自己知道,这样你的加密才是安全的,还可以包含一些自定义的用户信息放在荷载信息里,

本文需要你具备javaSE的基础, 所涉及的jar包如下:

  1. <!-- JWT javawebToken-->
  2. <dependency>
  3. <groupId>io.jsonwebtoken</groupId>
  4. <artifactId>jjwt</artifactId>
  5. <version>0.9.1</version>
  6. </dependency>
  7. <!-- 阿里巴巴json -->
  8. <dependency>
  9. <groupId>com.alibaba</groupId>
  10. <artifactId>fastjson</artifactId>
  11. <version>1.2.4</version>
  12. </dependency>

jwt 如何生成Token呢?

注意:这里使用的阿里巴巴提供的json工具包,实现序列化,后续会贴上所用的jar

  1. /**
  2. * token 工具类
  3. * @author 郎俊楠
  4. *
  5. */
  6. public class JwtUtil {
  7. private static Logger logger = Logger.getLogger(JwtUtil.class);
  8. public static final String TOKEN_HEADER = "Authorization";//token的key 也是名 不要写成token这样,要按照规范来
  9. public static final String TOKEN_PREFIX = "Bearer ";//token值的前缀,这是一种规范 ok
  10. private static final String SECRET = "mrLang";//你自己定的字符串 别让别人知道,加密时候用 是对称的秘钥 盐
  11. public static final String FUNCTS = "FUNCTS";//获取用户的功能使用的key
  12. public static final String USERINFO = "USER";//获取用户使用的key
  13. private static final long EXPIRATION = 1800L;// token的生命周期30分
  14. /**
  15. * 创建token令牌 以下为参数都是自定义信息
  16. * @param loginName 一般我们放用户的唯一标识登录名
  17. * @param functs 当前用户的功能集合, 本人的rbac权限比较个性化且很负责,一般你们放role角色就可以了
  18. * @param user 当前用户
  19. * @return
  20. */
  21. public static String createToken(String loginName, List<Object> functs, Users user) {
  22. Map<String, Object> map = new HashMap<>();
  23. //当前用户拥有的功能
  24. map.put(FUNCTS, JsonUtil.set(functs));
  25. //当前用户信息
  26. map.put(USERINFO, JsonUtil.set(user));
  27.  
  28. String token = Jwts.builder()
  29. .setSubject(loginName)//主题 主角是谁? 赋值登录名
  30. .setClaims(map)
  31. .setIssuedAt(new Date())//设置发布时间,也是生成时间
  32. .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION * ))//设置过期时间
  33. .signWith(SignatureAlgorithm.HS256, SECRET)//设置HS256加密,并且把你的盐 放里,这里推荐使用SH256证书加密
  34. .compact();//创建完成
  35. return token;
  36. }

jwt 如何验证Token是否过期呢?

  1. // token是否过期
  2. public static boolean isExpiration(String token) {
  3. try {
  4. return getTokenBody(token).getExpiration().before(new Date());
  5. } catch (Exception e) {
  6. return true;
  7. }
  8. }

jwt 如何获取自定义的信息呢?

  1. // 获取主角,登录名
  2. public static String getUserName(String token) {
  3. return getTokenBody(token).getSubject();
  4. }
  5.  
  6. // 获取token中存储的功能
  7. public static List<Object> getUserFuncts(String token) {
  8. String str = getTokenBody(token).get(FUNCTS).toString();
  9. List<Object> list = JsonUtil.getArray(str);
  10. return list;
  11. }
  12.  
  13. // 获取token存储的用户
  14. public static Object getUser(String token) {
  15. String str = getTokenBody(token).get(USERINFO).toString();
  16. return JsonUtil.getObj(str);
  17. }
  18.  
  19. // 公共获取自定义数据
  20. public static Claims getTokenBody(String token) {
  21. return Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody();
  22. }

jwt 如何刷新Token呢?

  1. // 刷新token
  2. public static String refreshToken(String token) {
  3. if (isExpiration(token)) {
  4. logger.info("token刷新失败!! 过期了!!");
  5. return null;
  6. }
  7. // 获取用户 权限信息
  8. String functs = getTokenBody(token).get(FUNCTS).toString();
  9. String user = getTokenBody(token).get(USERINFO).toString();
  10. String username = getTokenBody(token).getSubject();
  11. Map<String, Object> map = new HashMap<>();
  12. map.put(FUNCTS, JsonUtil.set(functs));
  13. map.put(USERINFO, JsonUtil.set(user));
  14. token = Jwts.builder().signWith(SignatureAlgorithm.HS256, SECRET).setClaims(map).setSubject(username)
  15. .setIssuedAt(new Date()).setExpiration(new Date(System.currentTimeMillis() + EXPIRATION * 1000))
  16. .compact();
  17. return token;
  18. }

token 如何发送给前端?.

传入 当前用户的 功能与用户信息,登录名 生成token,写入response的返回头中,前端获取后保存在前端的本地缓存中,后续前端请求要把token放在 头header里

  1. //登录成功之后
  2. List<Object> functs=(List<Object>) authResult.getAuthorities();//当前功能列表
  3. String loginName=authResult.getName();//登录名
  4. Users obj=(Users)authResult.getPrincipal();//用户信息
  5. String token=JwtUtil.createToken(loginName,functs,obj);//生成token
  6. //TOKEN_HEADER= Authorization TOKEN_PREFIX=Bearer token值
  7. response.setHeader(JwtUtil.TOKEN_HEADER,JwtUtil.TOKEN_PREFIX+token);
  8. response.setContentType("application/json;charset=utf-8");
  9. response.setStatus(HttpServletResponse.SC_OK);
  10. //个人编写的视图对象
  11. DTO dto=new DTO<>();
  12. dto.setCode("000000");
  13. dto.setMessage("认证通过");
  14.  
  15. PrintWriter pw=response.getWriter();
  16. pw.write(JsonUtil.set(dto));//写入json
  17. pw.flush();//强制刷新
  18. pw.close();//关闭流

用户请求携带token如何验证?

你可以自定义一个过滤器,或者使用某某框架,自定义拦截器,或者aop

  1. String header = request.getHeader(JwtUtil.TOKEN_HEADER);
  2. if (null == header || !header.toLowerCase().startsWith(JwtUtil.TOKEN_PREFIX)) {
  3. // 如果头部 Authorization 未设置或者不是 basic 认证头部,则当前
  4. // 请求不是该过滤器关注的对象,直接放行,继续filter chain 的执行
  5. chain.doFilter(request, response);
  6. return;
  7. }
  8. try {
  9. String token = header.replace(JwtUtil.TOKEN_PREFIX, "");
  10. // 验证token是否过期
  11. if(JwtUtil.isExpiration(token)){
  12. throw new javax.security.sasl.AuthenticationException("token 验证不通过");
  13. }
  14. //檢查token是否能解析
  15. Users user = (Users) JwtUtil.getUser(token);
  16. if (null == user) {
  17. throw new javax.security.sasl.AuthenticationException("token 验证不通过");
  18. }
  19.  
  20. //验证成功

总结:

使用jwt生成 一个具备有效期的token令牌, 这个token里面存储着 token本身的结构,加上token的过期时间,和一个你自己定义的字符串类似于加密 ,也就是签名所用的盐,这个盐只有你自己知道,这样你的加密才是安全的,还可以包含一些自定义的用户信息放在荷载信息里,本文所用的HS256+盐 对token加密是没有RS256安全的,

JWT签名算法中HS256和RS256有什么区别?

JWT签名算法中,一般有两个选择,一个采用HS256,另外一个就是采用RS256。
签名实际上是一个加密的过程,生成一段标识(也是JWT的一部分)作为接收方验证信息是否被篡改的依据。

RS256 (采用SHA-256 的 RSA 签名) 是一种非对称算法, 它使用公共/私钥对: 标识提供方采用私钥生成签名, JWT 的使用方获取公钥以验证签名。由于公钥 (与私钥相比) 不需要保护, 因此大多数标识提供方使其易于使用方获取和使用 (通常通过一个元数据URL)。
另一方面, HS256 (带有 SHA-256 的 HMAC 是一种对称算法, 双方之间仅共享一个 密钥。由于使用相同的密钥生成签名和验证签名, 因此必须注意确保密钥不被泄密。

在开发应用的时候启用JWT,使用RS256更加安全,你可以控制谁能使用什么类型的密钥。另外,如果你无法控制客户端,无法做到密钥的完全保密,RS256会是个更佳的选择,JWT的使用方只需要知道公钥。

建议:

为了双重保险,建议您使用RS256,最好是生成一个证书 读取使用证书里面的公钥加密,私钥留着以后每次前端请求验证token的合法性就可以了
jwt提供了方法可以验证token的合法性,过期时间,还可以根据token读取用户信息,这样你把token存储前端的localstorage中,
后端的缓存都省了

这样做安全么?
你要知道 RS256非对称加密都是一套体系的,公钥私钥是一组, 都存在的后端,别人不进你服务器盗取你就是安全的,要是真能登录你服务器那就直接删你库了,同样本文用大的对称加密也是 你自定定义的秘钥 盐 本文的mrlang都是存在你自己的服务器中,别人是不知道的,

分布式中如何验证Token?

你可以把token工具类copy到不同的机器上,让每台机器自己去做验证,只要你每台机器token工具类里存储的 盐或者一对秘钥 都一致 那么验证就会得到一致通过 ,这样做的好处就是 你不必远调用远程验证服务器了,所以真的很好用,换个思维想想 你去调用验证服务器还需要花费很多时间,这对访问量特别大的项目来说,压力真的不小,所以本文的JWT Token 不管作为单机,集群,分布式  你都值得拥有

本文作者为本人原创:如需转载 请携带出处 谢谢!!!!

jwt的token如何使用的更多相关文章

  1. 使用 JWT 生成 Token 代码示例

    JSON Web Token,简称 JWT, 是一个开放的标准(RFC 7519),它定义了以一种紧凑的.自包含的 JSON 对象在各方之间安全传输信息的方式.该信息含有数字签名,可以被验证和信任. ...

  2. ASP.NET WebApi 基于JWT实现Token签名认证

    一.前言 明人不说暗话,跟着阿笨一起玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性.那么对于我们来说,如何确保数据的安全将会是需要思考的问题.在ASP.NET WebServi ...

  3. 国服最强JWT生成Token做登录校验讲解,看完保证你学会!

    转载于:https://blog.csdn.net/u011277123/article/details/78918390 Free码农 2017-12-28 00:08:02 JWT简介 JWT(j ...

  4. SpringBoot集成JWT实现token验证

    原文:https://www.jianshu.com/p/e88d3f8151db JWT官网: https://jwt.io/ JWT(Java版)的github地址:https://github. ...

  5. 基于JWT的Token开发案例

    代码地址如下:http://www.demodashi.com/demo/12531.html 0.准备工作 0-1运行环境 jdk1.8 maven 一个能支持以上两者的代码编辑器,作者使用的是ID ...

  6. 利用jwt生成token,用于http请求身份验证

    前段时间在做移动端接口过程中,考虑到安全性,所有移动端发送请求(除了登录请求)过程中进行token有效验证. 1.利用jwt生成token a.导入jwt相关包 <!-- jwt --> ...

  7. tp5使用jwt生成token,做api的用户认证

    首先 composer 安装  firebase/php-jwt github:https://github.com/firebase/php-jwt composer require firebas ...

  8. token 与 基于JWT的Token认证

    支持跨域访问,无状态认证 token特点 支持跨域访问: Cookie是不允许垮域访问的,这一点对Token机制是不存在的,前提是传输的用户认证信息通过HTTP头传输 无状态(也称:服务端可扩展行): ...

  9. 基于JWT的Token认证机制及安全问题

    [干货分享]基于JWT的Token认证机制及安全问题 https://bbs.huaweicloud.com/blogs/06607ea7b53211e7b8317ca23e93a891

  10. springboot+jwt实现token登陆权限认证

    一 前言 此篇文章的内容也是学习不久,终于到周末有时间码一篇文章分享知识追寻者的粉丝们,学完本篇文章,读者将对token类的登陆认证流程有个全面的了解,可以动态搭建自己的登陆认证过程:对小项目而已是个 ...

随机推荐

  1. python学习笔记(13)常用模块列表总结

    os模块: os.remove() 删除文件 os.unlink() 删除文件 os.rename() 重命名文件 os.listdir() 列出指定目录下所有文件 os.chdir() 改变当前工作 ...

  2. Navicat 12 无限期试用

    最近发现navicat12又过期了,以前的是用的破解软件,然后是到1899年过期哈哈哈哈哈哈.重装了系统后,软件也重装了,发现破解软件不好使了,就先试用了,现在到期了.很是难受,这可咋整,不过在网上看 ...

  3. F5 BIG-IP之一前期随笔(应用交付网络产品)

    ADN:应用交付网络 TMOS:  Traffic  managment  operation  system  (流量管理系统) 一个实时的全应用代理流量管理操作系统             PVA ...

  4. 吴裕雄--天生自然 HADOOP大数据分布式处理:使用WinSCP连接本机与虚拟机

  5. go proxy转发工作中碰到的问题

    A-B 需求是一个中转 A-Proxy-B 读取来源请求A,在proxy读取body作些处理,再转给B,再把返回内容转给A 问题出在proxy这里 如果先把请求给B,再读body res, err : ...

  6. Python使用pycharm导入pymysql(MySQL)或pymssql(SQLServer)

    file->setting->project->project interperter,双击右侧出现的pip,弹出安装包,搜索pymysql->选择第一个->Instal ...

  7. OSI体系结构(七层)

    OSI体系结构,意为开放式系统互联.国际标准组织(国际标准化组织)制定了OSI模型.这个模型把网络通信的工作分为7层,分别是物理层.数据链路层.网络层.传输层.会话层.表示层和应用层. 1至4层被认为 ...

  8. 三分钟学会使用Derby数据库

    Derby数据库是一个纯用Java实现的内存数据库,属于Apache的一个开源项目.由于是用Java实现的,所以可以在任何平台上运行:另外一个特点是体积小,免安装,java1.6开始集成了derby数 ...

  9. nodejs日常总结

    1.node -v 查看当前node版本 2.npm root -g 查看npm安装路径(还有通过npm安装的vue-cli的路径) 默认: /usr/local/lib/node_modules r ...

  10. SpringMVC之请求响应(上)

    1.OutPutController package com.tz.controller; import java.util.Map; import org.springframework.stere ...