JWT——Token认证的两种实现和安全详解

2023-10-30

前言:

最近因为项目中需要解决跨域取值的问题,所有考虑到用Token认证做技术支撑点,自己看了许多与之相关的文章,从中总结出了以下两个要点(签名和token时间)。在说这两个要点之前先大概简单说一下与之有关的一些问题。
首先,如果你对token认证的知识一点都不了解,那么我觉得这篇文章还不太适合你,因为我在这里不会在把相关的基础知识再说明一遍,因为网上有很多相关的文章,讲的都比较好,我会在文章下边参考文献中附上链接。但是还是说一下重点的几个点:
1. header(头部),头部信息主要包括(参数的类型--JWT,签名的算法--HS256)
2. poyload(负荷),负荷基本就是自己想要存放的信息( 因为信息会暴露,不应该在载荷里面加入任何敏感的数据),有两个形式,下边会讲到
3. sign(签名),签名的作用就是为了防止恶意篡改数据,下边会详细说明
我的理解,在Java的实现中可以有两种方式,一种是不借助第三方jar,自己生成token,另一种的借助第三方jar,传入自己需要的负荷信息,生成token。接下来就根据这两个逐个说明。Token的组成就是header.poyload.sign。

自己生成token:

看过参考资料的朋友应该都知道,header和poyload的组成都是json字符串,所以先创建头部的json,然后用base64编码(org.apache.axis.encoding.Base64),这里选择的base64要对应着编码和解码( Base64是一种编码,也就是说,它是可以被翻译回原来的样子来的。它并不是一种加密过程)。然后再创建负荷的json,然后也同样用base64编码,这样就生成了两个字符串,然后用.拼接到一起就形成了现在的形式: eyJ 0 eXAiOiJKV 1 QiLCJhbGciOiJIUzI 1 NiJ9 .eyJmc m9 tX 3 VzZXIiOiJCIiwidGFyZ 2 V 0 X 3 VzZXIiOiJBI n0。在这里只是给大家一个演示,
实际中根据每个人的负荷参数的不同,编码后所生成的字符串也不同。 因为没有借助第三方的jar,
所有接下来要对上边拼接成的字符串进行hs256的算法加密生成sign签名,这里需要自己手动去写一个类,然后提供一
个静态方法供外界的调用。
类的实现代码如下:
import javax.crypto.Mac; 
import javax.crypto.spec.SecretKeySpec; 
import org.apache.commons.codec.binary.Base64; 

public class HS256 { 
    public static String returnSign(String message) { 
    String hash = ""; 
    //别人篡改数据,但是签名的密匙是在服务器存储,密匙不同,生成的sign也不同。 //所以根据sign的不        同就可以知道是否篡改了数据。 
    String secret = "mystar";//密匙 
    try { 
      Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); 
      SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(),"HmacSHA256"); 
      sha256_HMAC.init(secret_key); 
      hash = Base64.encodeBase64String(sha256_HMAC.doFinal(message.getBytes())); 
      System.out.println(message+"#####"+hash); 
    } catch (Exception e) {
      System.out.println("Error"+e); 
     } 
      return hash;
   } 
}

这样token的三部分就生成了,然后当做参数传到前台, 用cookie存储就可以在同一客 户端调用了。
当从客户端带过来token参数的时候,直接对头部和负荷再次调用加密算法,看生成的新的签名和之前的签名是否一致,
判断数据是否被篡改。

借用第三方的jar(jjwt-0.7.0.jar)生成token:

在这里自己已经通过代码测试,直接先看代码:

调用这个方法会自动对header和poyload进行 base64的编码,你看过源码就知道它用的是哪一种,用的是自己jar包自带的( io.jsonwebtoken.impl.Base64Codec),跟自己生成token时,用的base64的jar不一样,自己在此列出来:
public static void main(String[] args) { 
     String token = createJWT("11","22","222",11); 
      System.out.println(token); 
    JSONObject json_header = new JSONObject(); 
    json_header.put("typ", "JWT");//类型 
    json_header.put("alg", "HS256");//加密算法  
    String header=org.apache.axis.encoding.Base64.
     encode(json_header.toString().getBytes()); 
  String header = Base64Codec.BASE64URL.encode(json_header.toString() .getBytes()); 
  String aa = Base64Codec.BASE64URL.decodeToString(header); 
  System.out.println(header + "--" + aa); 
}

接着上边createJWT()方法说,只要把自己定义的负荷json串当做参数传入就行,并且签名也会对应的生成,返回一个完整的token。在测试的过程中,发现即使自己不定义token的头部,也会自动生成header,只是里边没有type这样的参数定义,只有HS256,这里源码里边,默认了alg的value。在这里我想说明的是, 假如外界会篡改参数,他肯定也知道构成,会把负荷里边的参数取出来,也许会修改,然后编码放回去,但是头部的信息对他来说用处不大,所以自己在这个方法里边,默认把头部加上,负荷的值还是自己在调用的时候传入进来。这样执行完,把生成的token就当做参数传到前台,存储在cookie里边。
然后再说一下,前台带过来token参数时候,怎么处理,看代码:
这个过程的原理跟自己生成token判断原理一样,都是从新生成sign,只是一个是调用自己的方法,另外一个是调用第三方的方法,自己看了源码(public abstract JwtBuilder signWith(SignatureAlgorithm paramSignatureAlgorithm, String paramString);),没能单独把第三方生成sign的方法提出来,只是一个接口,但是跟上边的加密算法实现原理应该是基本一致的。
至此,token签名这一块的问题大致就先说到这了,然后再来说一下token过期时间问题。这个相对来说不是太复杂,可以在负荷里边多带一个参数,把过期时间放进去,其实里边有一个exp标签名就是存储过期时间字段的,但是自己在测试过程中,发现每次读出来的都是最原始的时间,自己当时也再花时间去看,因为我觉得自己带参数其实一个道理。存储的是时间戳。
存储:
long nowMillis = System.currentTimeMillis();
long expMillis = nowMillis + 1000*2;//设置token二秒过期
获取:
Date aa = new Date(Long.parseLong(claims.get("aa").toString()));
方式就是这样了,我大概列了出来。到时可以存储一个生成token时间和token过期时间,然后服务器接收到的时候,可以根据当前的时间去判断。当前时间大于token生成时间并且小于token过期时间的情况下,继续走你接下来的业务操作。
附上参考文献:
http://blog.csdn.net/u011537073/article/details/52177204
http://www.cnblogs.com/anny0404/p/5318692.html
http://blog.leapoahead.com/2015/09/06/understanding-jwt/
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JWT——Token认证的两种实现和安全详解 的相关文章

随机推荐

  • 【speech&nlp】如何实现总体数据按照长短排序,同样长度数据随机排序

    在做speech nlp任务时 经常有这样一个需求 假设有一个数据集 有1000条数据 但是只有100种长度 所以必然存在某些数据是一样长的 我们想要让总体按照长短排序 但是同样长的数据要随机排序 经过了这个操作 再分batch 这样的效果
  • jmeter做接口压力测试_jmeter接口性能测试

    jmeter是apache公司基于java开发的一款开源压力测试工具 体积小 功能全 使用方便 是一个比较轻量级的测试工具 使用起来非常简单 因为jmeter是java开发的 所以运行的时候必须先要安装jdk才可以 jmeter是免安装的
  • 解决vscode找不到Python自定义模块,报错No module named ‘xxx‘

    笔者最近在学习python过程中 把在pycharm运行成功的项目放在vscode中 发现一些报错 比如找不到笔者自定义的模块 参考了一些说法与办法 现将解决方法记录于此 前言 vscode之所以找不到自定义模块 与其PYTHONPATH有
  • 将yolov5检测结果保存成json文件

    将yolov5检测结果保存成json文件 每帧图片对应一个json文件 json文件中包含图片名称 检测到的bbox信息 分类结果 中心坐标和置信度 函数json add以图片名 该图像内的所有bbox信息 以及bbox数量为输入 在yol
  • PCB画板(Altium Designer)

    b站学习视频 1 https www bilibili com video BV1ei4y1L7TU spm id from 333 999 0 0 这力荐 2 https www bilibili com video BV1tE411g7
  • 判断多边形凹凸

    任意给定一个多边形 判断它是凸还是凹 多边形的顶点以逆时针方向的序列来表示 include
  • 关于小程序中如何获取openid

    想要获取用户的openid首先要明白获取的过程 1 登录 2 发请求获取openid 实现 先定义一组数据 后面发请求获取openid时要的参数 一个是appid 一个是secret秘钥 这两个在注册开发者平台后可以查到 如下 global
  • 【Vulnhub系列】DC1

    文章目录 基本信息 实验过程 额外内容 使用CVE2014 3704添加管理账号 另一种查询具有root权限命令的find语句 下载地址 https www vulnhub com entry dc 1 1 292 基本信息 Kali 19
  • Counterfactual Zero-Shot and Open-Set Visual Recognition

    Counterfactual Zero Shot and Open Set Visual Recognition 1 Introduction 文献提出一个反事实框架 是由对不可见类的泛化来支撑的 作者基于反事实的一致性规则 反事实确实是基
  • C++同步技术——Mutex相关 (转)

    进程的互斥运行 正常情况下 一个进程的运行一般是不会影响到其他正在运行的进程的 但是对于某些有特殊要求的如以独占方式使用串行口等硬件设备的程序就要求在其进程运行期间不允许其他试图使用此端口设备的程序运行的 而且此类程序通常也不允许运行同一个
  • 大数据技术面试-Flume、kafka

    大数据技术面试 Flume kafka 1 Flume组成有哪些 2 Flume拦截器有哪些知识点 3 Flume采集数据会丢失吗 4 FileChannel如何优化 5 如何控制Kafka丢不丢数据 6 Kafka分区分配策略默认哪两种
  • 【华为机试刷题笔记】HJ26-字符串排序

    题目描述 编写一个程序 将输入字符串中的字符按如下规则排序 规则 1 英文字母从 A 到 Z 排列 不区分大小写 如 输入 Type 输出 epTy 规则 2 同一个英文字母的大小写同时存在时 按照输入顺序排列 如 输入 BabA 输出 a
  • I.MX6U开发板交叉编译Qt项目(什么是交叉编译器;如何搭建Qt交叉编译环境;WinSCP将Windows中的文件传到Ubuntu中;如何将编译好的执行文件拷到开发板上)

    文章目录 1 关于嵌入式学习的一些思考 1 1 使用imx6 还是stm32mp 1 2 关于是否需要买板子 2 I MX6U开发板交叉编译Qt项目 2 1 什么是交叉编译器 2 2 安装交叉编译器 2 2 1 下载交叉编译器和资料 2 2
  • 用FLEX实现屏幕快照及下载 flex导出excel文件

    用FLEX实现屏幕快照及下载 Flex Flash Flex2 Flex3 GgNET 01月 31st 2008 2 53am 这种方式 在服务器端不会在磁盘上生成图片FLEX代码public function printMap void
  • 分析脚本搭建docker环境:python, R

    1 搭建Anaconda Python3 6 FROM nvidia cuda 8 0 cudnn6 devel ubuntu16 04 MAINTAINER Tyan
  • TP-Link-IPC使用rtsp推流

    文章目录 1 安装 2 使用 3 RTSP 1 安装 电源 WIFI 2 使用 扫码或官网下载APP 登录绑定查看IP 登录IE浏览器 输入账号密码默认admin 123456 3 RTSP 注意 通过RTSP可以取视频流 但不支持控制云台
  • Linux samba网络传输服务

    Linux samba网络传输服务 本文章适合的读者 Linux初 中级用户 开源软件爱好者 大中专院校的学生 社会培训学生 Linux下的开发人员 samba 使用smb协议的应用程序 主要用于文件共享 SMB service messa
  • 实验七-卷积编码的MATLAB实现

    信息论编码实验3 9连载 更多看专栏 实验七 卷积编码的MATLAB实现 一 卷积码原理介绍 1 1 基本概念 1 2 n k N 卷积编码 1 2 1 编码 1 2 2 译码 Viterbi 译码算法 二 代码展示及运行结果 2 1 2
  • Mybatis处理一对多关系时的性能考虑

    Mybatis对于处理一对多的情况有三种解决方案 查询的时候join子表 然后交由mybatis拼装 查询的时候不join子表 另外发起select去抓取子表数据 和第二种类似 只不过利用fetchType lazy来延缓抓取的时机 这三种
  • JWT——Token认证的两种实现和安全详解

    前言 最近因为项目中需要解决跨域取值的问题 所有考虑到用Token认证做技术支撑点 自己看了许多与之相关的文章 从中总结出了以下两个要点 签名和token时间 在说这两个要点之前先大概简单说一下与之有关的一些问题 首先 如果你对token认