前言

前端时间和我朋友写了一个简易用户管理后台,功能其实很简单,涉及到的技术栈有: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. 数据表管理admin

    知识预览 admin组件使用 admin源码解析 回到顶部 admin组件使用 Django 提供了基于 web 的管理工具. Django 自动管理工具是 django.contrib 的一部分.你 ...

  2. 想转行做程序员,是学习JAVA还是Python?哪个更好?

    请大家务必审题,转行做程序员,是程序员,并非数据分析也不是软件测试. 首先声明:这是一篇容易引起撕逼的问答,为了祖国和谐,人民安康,请各位看官尽量理性讨论. 同时,这篇文章是面向一些初入行的朋友进行一 ...

  3. 想转行做3D游戏模型,如何快速入行

    随着技术和硬件迭代,3D建模,广泛运用在游戏,影视,动画,VR等领域,而且就业面非常广. 由于3D美术设计师薪资和前景确实都不错,很多同学想进入这个行业,从事相关工作,但是没有一个整体的学习思路和规划 ...

  4. 超级好用的c#解析JSON

    分享c# 一款非常好用的操作Json的dll,litjson VS2017 NuGet 搜索litjson,如下图: 例子: 在项目中新建一个txt文本文件,内容如下: [ { , "use ...

  5. phpstorm中xdebug配置和断点调试

    今天赶紧把这个搞了  运行环境: phpStorm 2018 PHP 5.45 nts VC9 Xdebug 2.4.1 0x01 PHP安装xdebug扩展 自己之前装一直没装起 原来是版本问题 下 ...

  6. Struts2:搭建原理

    记录下,struts2的搭建过程: 1核心jar包: struts-2.1.8\apps\struts2-blank-2.1.8.war 解压后 在struts2-blank-2.1.8\WEB-IN ...

  7. SpringCloud之RefreshScope 源码解读

    SpringCloud之RefreshScope @Scope 源码解读 Scope(org.springframework.beans.factory.config.Scope)是Spring 2. ...

  8. linux-查看服务器内存使用情况(free top)

    free命令:显示系统使用和空闲的内存情况,包括物理内存.交互区内存(swap)和内核缓冲区内存. [root@ipha-dev71- workspace]# free # kb total used ...

  9. python学习-多线程并发

    1.线程与进程 通俗解释: 对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进 ...

  10. 2.2 C语言_实现数据容器vector(排序功能)

    上一节我们说到我们己经实现了一般Vector可以做到的自动扩充,告诉随机存取,那么现在我们需要完成vector的一个排序的功能. 排序算法我们网上一百度哇~~!很常见的就有8大排序算法: 1.选择排序 ...