详解JWT token心得与使用实例


Posted in Javascript onAugust 02, 2019

本文你能学到什么?

token的组成
token串的生成流程。
token在客户端与服务器端的交互流程
Token的优点和思考
参考代码:核心代码使用参考,不是全部代码

JWT token的组成

头部(Header),格式如下:

{ 
“typ”: “JWT”, 
“alg”: “HS256” 
}

由上可知,该token使用HS256加密算法,将头部使用Base64编码可得到如下个格式的字符串:

eyJhbGciOiJIUzI1NiJ9

有效载荷(Playload):

{ 
“iss”: “Online JWT Builder”, 
“iat”: 1416797419, 
“exp”: 1448333419, 
……. 
“userid”:10001 
}

有效载荷中存放了token的签发者(iss)、签发时间(iat)、过期时间(exp)等以及一些我们需要写进token中的信息。有效载荷也使用Base64编码得到如下格式的字符串:

eyJ1c2VyaWQiOjB9

签名(Signature):

将Header和Playload拼接生成一个字符串str=“eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyaWQiOjB9”,使用HS256算法和我们提供的密钥(secret,服务器自己提供的一个字符串)对str进行加密生成最终的JWT,即我们需要的令牌(token),形如:str.”签名字符串”。

token在服务与客户端的交互流程

1:客户端通过用户名和密码登录
2:服务器验证用户名和密码,若通过,生成token返回给客户端。
3:客户端收到token后以后每次请求的时候都带上这个token,相当于一个令牌,表示我有权限访问了
4:服务器接收(通常在拦截器中实现)到该token,然后验证该token的合法性(为什么能验证下面说)。若该token合法,则通过请求,若token不合法或者过期,返回请求失败。

关于Token的思考

服务如何判断这个token是否合法?

由上面token的生成可知,token中的签名是由Header和有效载荷通过Base64编码生成再通过加密算法HS256和密钥最终生成签名,这个签名位于JWT的尾部,在服务器端同样对返回过来的JWT的前部分再进行一次签名生成,然后比较这次生成的签名与请求的JWT中的签名是否一致,若一致说明token合法。由于生成签名的密钥是服务器才知道的,所以别人难以伪造。

token中能放敏感信息吗?
不能,因为有效载荷是经过Base64编码生成的,并不是加密。所以不能存放敏感信息。

Token的优点

(1)相比于session,它无需保存在服务器,不占用服务器内存开销。
(2)无状态、可拓展性强:比如有3台机器(A、B、C)组成服务器集群,若session存在机器A上,session只能保存在其中一台服务器,此时你便不能访问机器B、C,因为B、C上没有存放该Session,而使用token就能够验证用户请求合法性,并且我再加几台机器也没事,所以可拓展性好就是这个意思。
(3)由(2)知,这样做可就支持了跨域访问。

Java实例:JWT token使用

部分代码来自互联网,找不到原作者了。。

编写JWT(Java Web Token)操作类:JavaWebToken

public class JavaWebToken {

  private static Logger log = LoggerFactory.getLogger(JavaWebToken.class);

  //该方法使用HS256算法和Secret:bankgl生成signKey
  private static Key getKeyInstance() {
    //We will sign our JavaWebToken with our ApiKey secret
    SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
    byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary("bankgl");
    Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
    return signingKey;
  }

  //使用HS256签名算法和生成的signingKey最终的Token,claims中是有效载荷
  public static String createJavaWebToken(Map<String, Object> claims) {
    return Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS256, getKeyInstance()).compact();
  }

  //解析Token,同时也能验证Token,当验证失败返回null
  public static Map<String, Object> parserJavaWebToken(String jwt) {
    try {
      Map<String, Object> jwtClaims =
          Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(jwt).getBody();
      return jwtClaims;
    } catch (Exception e) {
      log.error("json web token verify failed");
      return null;
    }
  }
}

编写登录Conreoller,在服务器端给客户返回token.

public LoginStatusMessage checkUserAndPassword(
  @RequestParam(value="username",required=true) String username,
  @RequestParam(value="password",required=true) String password,User user,HttpServletRequest request) throws Exception{
    User u = new User();
    //登录成功
    if((u = userService.checkUsernameAndPassword(user)) != null){
      Map<String,Object> m = new HashMap<String,Object>();
      m.put("userid", user.getUserid());
      String token = JavaWebToken.createJavaWebToken(m);
      System.out.println(token);
      LoginStatusMessage lsm = new LoginStatusMessage();
      lsm.setUser(u);
      lsm.setToken(token);
      return lsm;
    };
    //登录失败,返回Null
    return null;
  }

在拦截器中对请求中的Token验证(部分代码,表示下意思):

String token = request.getParameter("token");
      if(JavaWebToken.parserJavaWebToken(token) != null){
        //表示token合法
        return true;
      }else{
        //token不合法或者过期
        return false;
      }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JQuery给元素添加/删除节点比如select
Apr 02 Javascript
完美兼容各大浏览器的jQuery仿新浪图文淡入淡出间歇滚动特效
Nov 12 Javascript
VS2008中使用JavaScript调用WebServices
Dec 18 Javascript
javascript实现简易计算器的代码
May 31 Javascript
jquery判断对象是否为空并遍历对象的简单实例
Jul 26 Javascript
Node.js中 __dirname 的使用介绍
Jun 19 Javascript
简单谈谈JS中的正则表达式
Sep 11 Javascript
seajs模块压缩问题与解决方法实例分析
Oct 10 Javascript
关于laydate.js加载laydate.css路径错误问题解决
Dec 27 Javascript
利用jqgrid实现上移下移单元格功能
Nov 07 Javascript
解决vue打包后刷新页面报错:Unexpected token
Aug 27 Javascript
vue中后端做Excel导出功能返回数据流前端的处理操作
Sep 08 Javascript
详解使用JWT实现单点登录(完全跨域方案)
Aug 02 #Javascript
基于mpvue的简单弹窗组件mptoast使用详解
Aug 02 #Javascript
vue下使用nginx刷新页面404的问题解决
Aug 02 #Javascript
超轻量级的js时间库miment使用解析
Aug 02 #Javascript
操作按钮悬浮固定在微信小程序底部的实现代码
Aug 02 #Javascript
微信小程序中悬浮窗功能的实现代码
Aug 02 #Javascript
微信小程序的授权实现过程解析
Aug 02 #Javascript
You might like
在MongoDB中模拟Auto Increment的php代码
2011/03/06 PHP
php设计模式之适配器模式实例分析【星际争霸游戏案例】
2020/04/07 PHP
告诉大家什么是JSON
2008/06/10 Javascript
使用自定义setTimeout和setInterval使之可以传递参数和对象参数
2009/04/24 Javascript
基于jQuery实现的水平和垂直居中的div窗口
2011/08/08 Javascript
js鼠标滑过弹出层的定位IE6bug解决办法
2012/12/26 Javascript
javascript中的undefined和not defined区别示例介绍
2014/02/26 Javascript
浅谈jQuery异步对象(XMLHttpRequest)
2014/11/17 Javascript
javascript高级编程之函数表达式 递归和闭包函数
2015/11/29 Javascript
遍历json获得数据的几种方法小结
2017/01/21 Javascript
javascript中mouseenter与mouseover的异同
2017/06/06 Javascript
JS实现下拉菜单列表与登录注册弹窗效果
2017/08/10 Javascript
微信小程序实现天气预报功能
2018/07/18 Javascript
Vue filter格式化时间戳时间成标准日期格式的方法
2018/09/16 Javascript
JavaScript实现的级联算法示例【省市二级联动功能】
2018/12/25 Javascript
微信小程序动态添加view组件的实例代码
2019/05/23 Javascript
TensorFlow.js 微信小程序插件开始支持模型缓存的方法
2020/02/21 Javascript
jquery+css3实现的经典弹出层效果示例
2020/05/16 jQuery
详解vue中v-model和v-bind绑定数据的异同
2020/08/10 Javascript
通过实例解析javascript Date对象属性及方法
2020/11/04 Javascript
在Python中封装GObject模块进行图形化程序编程的教程
2015/04/14 Python
python虚拟环境virtualenv的安装与使用
2017/09/21 Python
浅谈python数据类型及类型转换
2017/12/18 Python
Python爬虫之pandas基本安装与使用方法示例
2018/08/08 Python
Django框架ORM数据库操作实例详解
2019/11/07 Python
python数据库操作mysql:pymysql、sqlalchemy常见用法详解
2020/03/30 Python
Python写捕鱼达人的游戏实现
2020/03/31 Python
python实现学生信息管理系统源码
2021/02/22 Python
办公室前台的岗位职责
2013/12/20 职场文书
《童趣》教学反思
2014/02/19 职场文书
湖南省党的群众路线教育实践活动总结会议新闻稿
2014/10/21 职场文书
2014年小学教师工作总结
2014/11/10 职场文书
2014年医院党建工作总结
2014/12/20 职场文书
幼儿体育课教学反思
2016/02/16 职场文书
微信小程序用户授权最佳实践指南
2021/05/08 Javascript
python中出现invalid syntax报错的几种原因分析
2022/02/12 Python