• 关于JWT


    目录

    一,jwt出现的原因及工作原理

    1. JWT是什么

    2. 为什么使用JWT 

    3. JWT的工作原理 

     4. JWT组成

    5. JWT的验证过程 

    二、jwt工具类介绍,三种场景

    ​三、jwt与vuex配合在SPA项目中的应用 


    一,jwt出现的原因及工作原理

    1. JWT是什么

     JSON Web Token (JWT),它是目前最流行的跨域身份验证解决方案

    2. 为什么使用JWT 

    JWT的精髓在于:“去中心化”,数据是保存在客户端的。

    3. JWT的工作原理 

       1. 是在服务器身份验证之后,将生成一个JSON对象并将其发送回用户,示例如下:
          {"UserName": "Chongchong","Role": "Admin","Expire": "2018-08-08 20:15:56"}

       2. 之后,当用户与服务器通信时,客户在请求中发回JSON对象
       3. 为了防止用户篡改数据,服务器将在生成对象时添加签名,并对发回的数据进行验证

     4. JWT组成

    一个JWT实际上就是一个字符串,它由三部分组成:头部(Header)、载荷(Payload)与签名(signature)

    5. JWT的验证过程 

    它验证的方法其实很简单,只要把header做base64url解码,就能知道JWT用的什么算法做的签名,然后用这个算法,再次用同样的逻辑对header和payload做一次签名,
       并比较这个签名是否与JWT本身包含的第三个部分的串是否完全相同,只要不同,就可以认为这个JWT是一个被篡改过的串,自然就属于验证失败了。
       接收方生成签名的时候必须使用跟JWT发送方相同的密钥

    二、jwt工具类介绍,三种场景

    1. package com.zking.vue.test;
    2. import java.text.SimpleDateFormat;
    3. import java.util.Date;
    4. import java.util.HashMap;
    5. import java.util.Map;
    6. import org.junit.Test;
    7. import com.zking.vue.util.JwtUtils;
    8. import io.jsonwebtoken.Claims;
    9. public class JwtDemo {
    10. private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
    11. @Test
    12. public void test1() {// 生成JWT
    13. Map<String, Object> claims = new HashMap<String, Object>();
    14. claims.put("username", "zss");
    15. claims.put("age", 18);
    16. String jwt = JwtUtils.createJwt(claims, JwtUtils.JWT_WEB_TTL);
    17. System.out.println(jwt);
    18. Claims parseJwt = JwtUtils.parseJwt(jwt);
    19. for (Map.Entry<String, Object> entry : parseJwt.entrySet()) {
    20. System.out.println(entry.getKey() + "=" + entry.getValue());
    21. }
    22. Date d1 = parseJwt.getIssuedAt();
    23. Date d2 = parseJwt.getExpiration();
    24. System.out.println("令牌签发时间:" + sdf.format(d1));
    25. System.out.println("令牌过期时间:" + sdf.format(d2));
    26. }
    27. @Test
    28. public void test2() {// 解析oldJwt
    29. // String oldJwt = "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjI5MDMzNjAsImlhdCI6MTU2MjkwMTU2MCwiYWdlIjoxOCwianRpIjoiZDVjMzE4Njg0MDcyNDgyZDg1MDE5ODVmMDY3OGQ4NjkiLCJ1c2VybmFtZSI6InpzcyJ9.XDDDRRq5jYq5EdEBHtPm7GcuBz4S0VhDTS1amRCdf48";
    30. String oldJwt = "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjM1MjU5MjMsImlhdCI6MTU2MzUyNDEyMywiYWdlIjoxOCwianRpIjoiOTAzNmMwY2Q3NGIwNDBjMzgzMDAxYzdiNmZkMzYzZmIiLCJ1c2VybmFtZSI6InpzcyJ9.sgV9fr4fgmmahDFRJnsfazA6R3H-gNMVcg2ucA227n4";
    31. Claims parseJwt = JwtUtils.parseJwt(oldJwt);
    32. for (Map.Entry<String, Object> entry : parseJwt.entrySet()) {
    33. System.out.println(entry.getKey() + "=" + entry.getValue());
    34. }
    35. Date d1 = parseJwt.getIssuedAt();
    36. Date d2 = parseJwt.getExpiration();
    37. System.out.println("令牌签发时间:" + sdf.format(d1));
    38. System.out.println("令牌过期时间:" + sdf.format(d2));
    39. }
    40. @Test
    41. public void test3() {// 复制jwt,并延时30
    42. String oldJwt = "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjI5MDMzNjAsImlhdCI6MTU2MjkwMTU2MCwiYWdlIjoxOCwianRpIjoiZDVjMzE4Njg0MDcyNDgyZDg1MDE5ODVmMDY3OGQ4NjkiLCJ1c2VybmFtZSI6InpzcyJ9.XDDDRRq5jYq5EdEBHtPm7GcuBz4S0VhDTS1amRCdf48";
    43. String jwt = JwtUtils.copyJwt(oldJwt, JwtUtils.JWT_WEB_TTL);
    44. Claims parseJwt = JwtUtils.parseJwt(jwt);
    45. for (Map.Entry<String, Object> entry : parseJwt.entrySet()) {
    46. System.out.println(entry.getKey() + "=" + entry.getValue());
    47. }
    48. Date d1 = parseJwt.getIssuedAt();
    49. Date d2 = parseJwt.getExpiration();
    50. System.out.println("令牌签发时间:" + sdf.format(d1));
    51. System.out.println("令牌过期时间:" + sdf.format(d2));
    52. }
    53. @Test
    54. public void test4() {// 测试JWT的有效时间
    55. Map<String, Object> claims = new HashMap<String, Object>();
    56. claims.put("username", "zss");
    57. String jwt = JwtUtils.createJwt(claims, 3 * 1000L);
    58. System.out.println(jwt);
    59. Claims parseJwt = JwtUtils.parseJwt(jwt);
    60. Date d1 = parseJwt.getIssuedAt();
    61. Date d2 = parseJwt.getExpiration();
    62. System.out.println("令牌签发时间:" + sdf.format(d1));
    63. System.out.println("令牌过期时间:" + sdf.format(d2));
    64. }
    65. @Test
    66. public void test5() {// 三秒后再解析上面过期时间只有三秒的令牌,因为过期则会报错io.jsonwebtoken.ExpiredJwtException
    67. String oldJwt = "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjI4NTMzMzAsImlhdCI6MTU2Mjg1MzMyNywidXNlcm5hbWUiOiJ6c3MifQ.e098Vj9KBlZfC12QSDhI5lUGRLbNwb27lrYYSL6JwrQ";
    68. Claims parseJwt = JwtUtils.parseJwt(oldJwt);
    69. // 过期后解析就报错了,下面代码根本不会执行
    70. Date d1 = parseJwt.getIssuedAt();
    71. Date d2 = parseJwt.getExpiration();
    72. System.out.println("令牌签发时间:" + sdf.format(d1));
    73. System.out.println("令牌过期时间:" + sdf.format(d2));
    74. }
    75. }


    三、jwt与vuex配合在SPA项目中的应用 

    1. // The Vue build version to load with the `import` command
    2. // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
    3. import Vue from 'vue'
    4. //process.env.MOCK && require('@/mock')
    5. import ElementUI from 'element-ui' // 新添加 1
    6. import 'element-ui/lib/theme-chalk/index.css' // 新添加 2 ,避免后期打包样式不同,要放在import App from './App'; 之前
    7. import App from './App'
    8. import router from './router'
    9. import axios from '@/api/http' //#vue项目对axios的全局配置
    10. //import axios from 'axios'
    11. import VueAxios from 'vue-axios'
    12. import store from './store'
    13. Vue.use(ElementUI); // 新添加 3
    14. Vue.use(VueAxios,axios);
    15. Vue.config.productionTip = false
    16. /* eslint-disable no-new */
    17. window.vm = new Vue({
    18. el: '#app',
    19. router,
    20. store,
    21. data(){
    22. return{
    23. //在vue根实例中定义一个变量,这个变量就是vue实例,它总线
    24. //props this.$emit
    25. Bus:new Vue({
    26. })
    27. }
    28. },
    29. components: { App },
    30. template: ''
    31. })
    1. /**
    2. * vue项目对axios的全局配置
    3. */
    4. import axios from 'axios'
    5. import qs from 'qs'
    6. //引入action模块,并添加至axios的类属性urls上
    7. import action from '@/api/action'
    8. axios.urls = action
    9. // axios默认配置
    10. axios.defaults.timeout = 10000; // 超时时间
    11. // axios.defaults.baseURL = 'http://localhost:8080/j2ee15'; // 默认地址
    12. axios.defaults.baseURL = action.SERVER;
    13. //整理数据
    14. // 只适用于 POST,PUT,PATCH,transformRequest` 允许在向服务器发送前,修改请求数据
    15. axios.defaults.transformRequest = function(data) {
    16. data = qs.stringify(data);
    17. return data;
    18. };
    19. // 请求拦截器
    20. axios.interceptors.request.use(function(config) {
    21. var jwt = window.vm.$store.getters.getJwt;
    22. config.headers['jwt'] = jwt;
    23. return config;
    24. }, function(error) {
    25. return Promise.reject(error);
    26. });
    27. // 响应拦截器
    28. axios.interceptors.response.use(function(response) {
    29. // debugger;
    30. var jwt = response.headers['jwt'];
    31. if(jwt){
    32. window.vm.$store.commit('setJwt',{jwt:jwt});
    33. }
    34. return response;
    35. }, function(error) {
    36. return Promise.reject(error);
    37. });
    38. // // 路由请求拦截
    39. // // http request 拦截器
    40. // axios.interceptors.request.use(
    41. // config => {
    42. // //config.data = JSON.stringify(config.data);
    43. // //config.headers['Content-Type'] = 'application/json;charset=UTF-8';
    44. // //config.headers['Token'] = 'abcxyz';
    45. // //判断是否存在ticket,如果存在的话,则每个http header都加上ticket
    46. // // if (cookie.get("token")) {
    47. // // //用户每次操作,都将cookie设置成2小时
    48. // // cookie.set("token", cookie.get("token"), 1 / 12)
    49. // // cookie.set("name", cookie.get("name"), 1 / 12)
    50. // // config.headers.token = cookie.get("token");
    51. // // config.headers.name = cookie.get("name");
    52. // // }
    53. // return config;
    54. // },
    55. // error => {
    56. // return Promise.reject(error.response);
    57. // });
    58. // // 路由响应拦截
    59. // // http response 拦截器
    60. // axios.interceptors.response.use(
    61. // response => {
    62. // if (response.data.resultCode == "404") {
    63. // console.log("response.data.resultCode是404")
    64. // // 返回 错误代码-1 清除ticket信息并跳转到登录页面
    65. // // cookie.del("ticket")
    66. // // window.location.href='http://login.com'
    67. // return
    68. // } else {
    69. // return response;
    70. // }
    71. // },
    72. // error => {
    73. // return Promise.reject(error.response) // 返回接口返回的错误信息
    74. // });
    75. export default axios;
    1. export default{
    2. setResName:(state,payload)=>{
    3. state.resName = payload.resName;
    4. },
    5. setJwt:(state,payload)=>{
    6. state.jwt = payload.jwt;
    7. }
    8. }
    1. export default{
    2. getResName:(state) => {
    3. return state.resName;
    4. },
    5. getJwt:(state) => {
    6. return state.jwt;
    7. },
    8. }

  • 相关阅读:
    2022-33周(8.08-8.14) 项目问题整理
    冥想第九百七十七天
    嘉泰实业:真实低门槛,安全有保障
    什么是算力托管
    Python 小贴士(3)
    《Java面向对象程序设计》学习笔记——第 15 章 Java 多线程机制
    Debezium系列之:Debezium技术专栏第300篇系列文章之打通Debezium实时采集Oracle数据库数据到Kafka集群的技术
    OLAP引擎也能实现高性能向量检索,据说QPS高于milvus!
    在公共Linux服务器上创建自己的python虚拟环境
    javax.net.ssl.SSLHandshakeException: Chain validation failed
  • 原文地址:https://blog.csdn.net/m0_67864917/article/details/126900734