前言

前端时间和我朋友写了一个简易用户管理后台,功能其实很简单,涉及到的技术栈有:vue+elementUI,java+spring MVC以及node+egg,数据库用的mysql,简单方便。

一开始是我是只负责前端,但是前端开发的的速度太快,老是没事,加上他小子并没有接触过实战的项目,又怕他出乱子,所以考虑我也写一个后端,

开始考虑的是用python+django,但是还是在半途放弃了,因为总感觉Django不过灵活,使用起来非常别扭,也可能是用scrapy写爬虫写多了,难以理解django的框架设计,总是会把他想象成一个scrapy架构,也导致代码写的很乱,下面上一张scrapy架构图。

所以最后考虑的用node,Express和Koa框架学习过node应该都知道,我以前也用过express(写过一个小demo),但是给我的感觉这到像是一个只能有5年以上node开发经验才能玩的转的,因为express是非常的精简的,安装它后,会发现它几乎不会为你提供任何编码规范,也没有约束你的框架应该怎么设计,以至于新手下载完成后完全不知道自己应该干嘛,甚至不知道直接的文件应该写在哪,没有框架本身的约定,标准的MVC模型有着千奇百怪的写法,所以我觉得没有一定的架构思想和经验是很难驾驭的。

koa我并没有直接的使用过,只是听说是express的原班人马打造的,中间件是基于洋葱圈模型实现的。下面上一张图洋葱圈模型图。

而是后来直接就接触的egg,egg标语是“为企业级框架和应用而生”,通道

废话说的有点多了,重点是通一套前端代码,开发了两套后端代码,功能是完全一致的,后端都实现了相应的jwt验证功能,-->json web token,密钥都是我们约定好的固定值,但是最后发现一样的密钥,相同的数据,使用的jwt包不同产生的结果也不同,这也就导致两端之间无法相互切换,每次切换必须从登陆重新开始,这不太符合逻辑,而且重要的是后面的安排有需要这样的功能,无法做到无缝切换就直接导致实现不了下面的功能。

提纲内容

  • jwt实现原理
  • jwt未能解决的疑惑
  • base64和base64url

jwt实现原理

其实作为一个前端开发人员,jwt实现原理我是没必要懂得的,但是如果你不限于此,这算是个必不可少的内容了吧。

先上一张图。

图中数字1是后端使用jwt工具包生成的token,通常是由三部分组成,也就是token中间的两个“.”将其分为三部分,第一部分对应的是右边的数字2部分,然后依次对应。

这三部分分别是头部、有效载荷、签名。

头部:alg是指说用到的算法,type当然是令牌类型

有效荷载:sub所签发的用户,name是签发者的姓名,lat是这签发时间,exp是指到期时间,当然还有一些其他的,这些数据都是非必要数据,实则只有exp可能有用,因为有效数据实际都是在data里面,当然你也可以不这么做。

签名:前两者都是通过base64url编码过的,而非是算法加密的,所以几乎是透明的。但是签名是默认是通过hsa256算法加密的 ,加密的规则是:

HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
your-256-bit-secret
)

如何验证token呢?那更加简单了,就是用前端传回来的token前两部分和服务器存的秘钥再次加密一次,然后做base64url处理和第三部分比较,一样代表这个token是自己签发的,不一样代表是伪造的,完了过后再将有效载荷部分进行base64url反编码,就得到exp,然后和当前时间比较是否过期。

jwt未能解决的疑惑

经过测试,发现三个问题。

1、 node和java使用对应的jwt工具包生成的token不相同,这里是指在一系列参数完全相同的情况下。

2、 还发现用java生成的token在jwt官网解析时候输入秘钥结果的到的签名和自己的签名不一样,但是node是一样的,于是就产生了java工具包在输入签名的时候对密钥进行了其他处理的想法,但是他并没有找出做出来怎么样的处理,也就是说我们在生成签名的时候根本就连密钥都是不一样的。

3、 不管是node还是java生成的token,我们用原来一模一样的数据和一样的算法公式都产生不了和工具包生成一样的签名,也就是可以怀疑在进行hsa256算法加密前确实对秘钥进行处理了。

base64和base64url

base64就是一种二进制编码方式,原理很简单,先准备一个包含64个字符的数组:

['A','B','C',...'a','b','c',...'0','1','2',...'+','/']

然后对二进制数据进行处理,每三个字节一组,一共24bit,一个字节8bit嘛,然后再将24分为4组,每组正好6bit。6bit的话就刚好能表示64个字符。如果编码字符不是3的倍数,就会剩下一个字节或者两个字节,这个时候就在后面填充\x00,再在编码末尾加上一个或者两个=号。解码的时候制动力去掉就好了。

base64url编码就是将字符编码成url能传递的参数,因为base64编码会出现+号和/号,然后就会在url中出现问题,所以base64url其实就是将+和/分别变成-和_

手写jwt验证,实现java和node无缝切换的更多相关文章

  1. 算法是什么(二)手写个链表(java)

    算法是什么(二)手写个链表(java)   liuyuhang原创,未经允许禁止转载 目录 算法是什么(〇) 很多语言的API中都提供了链表实现,或者扩展库中实现了链表. 但是更多的情况下,Map(或 ...

  2. 手写代码注意点--java.lang.Math 相关

    1-如果用到了Math的函数,需要手动写上: import java.lang.Math; 2-求x的y次方,用的是Math.pow(x,y); 注意,返回值是double!!! 不是int, 如果需 ...

  3. 手写代码注意点--java.util.Stack相关

    1-Stack的基本函数为: 注意: 取栈顶的函数为peek(),不是top()... 测试stack是否为空的函数为empty(),不是isEmpty()...

  4. java 从零开始手写 RPC (07)-timeout 超时处理

    <过时不候> 最漫长的莫过于等待 我们不可能永远等一个人 就像请求 永远等待响应 超时处理 java 从零开始手写 RPC (01) 基于 socket 实现 java 从零开始手写 RP ...

  5. 2 手写Java LinkedList核心源码

    上一章我们手写了ArrayList的核心源码,ArrayList底层是用了一个数组来保存数据,数组保存数据的优点就是查找效率高,但是删除效率特别低,最坏的情况下需要移动所有的元素.在查找需求比较重要的 ...

  6. 阿里第二轮面试:手写Java二叉树

    阿里面试 现在很多公司在招聘开发岗位的时候,都会事先在招聘信息中注明面试者应当具备的知识技能,而且在面试的过程中,有部分对于技能掌握程度有严格要求的公司还会要求面试者手写代码,这个环节很考验面试者的基 ...

  7. 教你如何使用Java手写一个基于链表的队列

    在上一篇博客[教你如何使用Java手写一个基于数组的队列]中已经介绍了队列,以及Java语言中对队列的实现,对队列不是很了解的可以我上一篇文章.那么,现在就直接进入主题吧. 这篇博客主要讲解的是如何使 ...

  8. 6 手写Java LinkedHashMap 核心源码

    概述 LinkedHashMap是Java中常用的数据结构之一,安卓中的LruCache缓存,底层使用的就是LinkedHashMap,LRU(Least Recently Used)算法,即最近最少 ...

  9. 使用java语言基于SMTP协议手写邮件客户端

    使用java语言基于SMTP协议手写邮件客户端 1. 说明 电子邮件是互联网上常见的应用,他是互联网早期的产品,直至今日依然受到广大用户的喜爱(在中国可能因为文化背景不同,电子邮件只在办公的时候常用) ...

随机推荐

  1. python编程基础之十一

    循环语句:周而复始,在满足某个条件下,重复做相同或类型的事情, 循环语句三要素:循环条件 + 循环体 + 循环条件改变while 条件 : 循环体 循环条件改变... while 条件 : 循环体 循 ...

  2. 了解ajax基本爬取方式

    '''爬去豆瓣电影数据了解ajax的基本爬去方式 ''' from urllib import requestimport jsonimport ssl url = "https://mov ...

  3. Java编程思想——第17章 容器深入研究 读书笔记(四)

    九.散列与散列码 HashMap使用equals()判断当前的键是否与表中存在的键相同. 正确的equals()方法需满足一下条件: 1)自反性.x.equals(x) 是true; 2)对称性.x. ...

  4. .NET Core API后台架构搭建

    ASP.NET Core API后台架构搭建 项目文件:https://files.cnblogs.com/files/ZM191018/WebAPI.zip 本篇可以了解到: 依赖注入 Dapper ...

  5. CTF-SMB渗透

    环境 Kali ip 192.168.56.102 Smb 靶机ip 192.168.56.103  靶场下载: 链接:https://pan.baidu.com/s/1OwNjBf7ZEGmFlRq ...

  6. PHP 组件注册的例子

    <?php namespace Test; abstract class Plugin { protected $pluginName = null; abstract public funct ...

  7. 一起来看一下Java中的Annotation注解

    目录: 一. 什么是Annotation 二. Annotation的作用 2.1 编译器使用到的注解 2.2 .class文件使用到的注解 2.3 运行期读取的注解 三. 定义Annotation ...

  8. [NOIP2013提高组]华容道

    这道题第一眼看是暴力,然后发现直接暴力会TLE. 把问题转换一下:移动空格到处跑,如果空格跑到指定位置的棋子,交换位置. 这个可以设计一个状态:$[x1][y1][x2][y2]$,表示空格在$(x1 ...

  9. C# 添加、修改、删除Excel图表数据标签

    图表中,图表数据标签以数据化形式表现图表中的特定数据,可增强图表的可读性.我们可以对图表添加数据标签,也可以对已有的数据标签进行修改或者删除,下面将通过C#代码形式来实现. 使用工具:Spire.XL ...

  10. 百万年薪python之路 -- HTML标签

    HTML标签 html标签分类 html标签又叫做html元素,它分为块级元素和内联元素(也可以叫做行内元素),都是html规范中的概念. 标题 h1 h2 h3 h4 h5 h6 列表 ol ul ...