IT修真院·小课堂丨互联网职业小课堂在线学习平台

课堂课题:

JWT简单介绍

关联任务:

任务五

直播时间:

2018-10-03 19:30:00


课堂内容:

视频链接:

PPT链接:

提交按钮:

小课堂内容格式


标题:

【修真院xx(职业)小课堂】课题名称

开场语:

大家好,我是IT修真院XX分院第X期的学员XX,一枚正直纯洁善良的XX程序员,今天给大家分享一下,修真院官网XX(职业)任务X,深度思考中的知识点——XXX

(1)背景介绍:

背景介绍的时候,尽可能的要宽广,讲清楚来龙去脉,讲清楚为什么会需要这个技术。

(2)知识剖析:

讲知识点的时候,尽可能的成体系,学会成体系的去给别人介绍知识。现在很多做的都是零散的,没有分类。

(3)常见问题:

最少列出1个常见问题。

(4)解决方案:

写清楚常见问题的解决方案。

(5)编码实战:

尽可能的去寻找在真实项目中在用的。如果你能找到某个网站在用你说的知识点,这是最好的。学以致用,否则当成练习题就没有意义了。多准备一些demo,讲解过程中将知识点和demo结合,便于大家理解所讲解的知识点。

(6)拓展思考:

知识点之外的拓展思考,由分享人进行讲解,这些东西就是所谓的深度,也是一个人技术水准高低比较的表现。

(7)参考文献:

引入参加文献的时候,在引用的句子后面加上序号【1】。参考文献中列出详细来源。不要去抄别人的东西,这是一个基本的态度。

(8)更多讨论:

Q1:提问人:问题?
A1:回答人(可以是分享人,也可以是其他学员):回答
Q2:提问人:问题?
A2:回答人(可以是分享人,也可以是其他学员):回答
Q3:提问人:问题?
A3:回答人(可以是分享人,也可以是其他学员):回答

(9)鸣谢:

感谢XX、XX师兄,此教程是在他们之前技术分享的基础上完善而成。

(10)结束语:

今天的分享就到这里啦,欢迎大家点赞、转发、留言、拍砖~

JWT简单介绍     中品

辅导师兄 [真传弟子]JAVA-刘凯


大家好,我是IT修真院郑州分院第11期的学员何爽,一枚正直纯洁善良的后端程序员,今天给大家分享一下,修真院官网java(职业)任务5,深度思考中的知识点——JWT简单介绍。

 

1.背景介绍

由于微服务大都是分布式的,需要几台服务器部署,当一个用户在其中一台服务器登录后,传统的方式是session保存其登录信息,然后可以使用共享存储共享,比如redis共享,这种方案的缺点在于共享存储需要一定保护机制,因此需要通过安全链接来访问,这时解决方案的实现就通常具有相当高的复杂性了,所以这里使用基于令牌的方式做登录。

 

什么是JWT

JWTJSON WEB TOKEN):JSON网络令牌,JWT是一个轻便的安全跨平台传输格式,定义了一个紧凑的自包含的方式在不同实体之间安全传输信息(JSON格式)。

它是在Web环境下两个实体之间传输数据的一项标准。实际上传输的就是一个字符串。

广义上讲JWT是一个标准的名称;狭义上JWT指的就是用来传递的那个token字符串

 

2.知识剖析

JWT的结构:

JWT包含了使用.分隔的三部分: Header 头部 Payload 负载 Signature 签名
其结构看起来是这样的Header.Payload.Signature
JWT
header 中承载了两部分信息

{
  "alg": "RS256",
  "typ": "JWT"
}
alg:
声明加密的算法
typ:
声明类型
对这个头部信息进行 base64,即可得到 header 部分

payload 是主体部分,意为载体,承载着有效的 JWT 数据包,它包含三个部分

标准声明
公共声明
私有声明


标准声明的字段

interface Stantar {
  iss?: string; // JWT
的签发者
  sub?: string; // JWT
所面向的用户
  aud?: string; //
接收JWT的一方
  exp?: number; // JWT
的过期时间
  nbf?: number; //
xxx日期之间,该JWT都是可用的
  iat?: number; //
JWT签发的时间
  jti?: number; //JWT
的唯一身份标识
}

 

 公共声明的字段

interface Public {
  [key: string]: any;
}
公共声明字段可以添加任意信息,但是因为可以被解密出来,所以不要存放敏感信息。

 

私有声明的字段

interface Private {
  [key: string]: any;
}
私有声明是 JWT 提供者添加的字段,一样可以被解密,所以也不能存放敏感信息。

signature(签名)

headerpayload对应的json结构进行base64url编码之后得到的字符串用点号拼接起来,然后根据header里面alg指定的签名算法生成出来的,然后添加自己设定的key进行加密签名。

 

JWT设计单点登录系统过程:

用户认证八步走

所谓用户认证(Authentication),就是让用户登录,并且在接下来的一段时间内让用户访问网站时可以使用其账户,而不需要再次登录的机制。

 

首先,服务器应用(下面简称“应用”)让用户通过Web表单将自己的用户名和密码发送到服务器的接口。这一过程一般是一个HTTP POST请求。建议的方式是通过SSL加密的传输(https协议),从而避免敏感信息被嗅探。


接下来,应用和数据库核对用户名和密码。

核对用户名和密码成功后,应用将用户的id(图中的user_id)作为JWT Payload的一个属性,将其与头部分别进行Base64编码拼接后签名,形成一个JWT。这里的JWT就是一个形同lll.zzz.xxx的字符串。

应用将JWT字符串作为该请求Cookie的一部分返回给用户。注意,在这里必须使用HttpOnly属性来防止Cookie被JavaScript读取,从而避免跨站脚本攻击(XSS攻击)。

在Cookie失效或者被删除前,用户每次访问应用,应用都会接受到含有jwt的Cookie。从而应用就可以将JWT从请求中提取出来。

应用通过一系列任务检查JWT的有效性。例如,检查签名是否正确;检查Token是否过期;检查Token的接收方是否是自己(可选)。

应用在确认JWT有效之后,JWT进行Base64解码(可能在上一步中已经完成),然后在Payload中读取用户的id值,也就是user_id属性。这里用户的id为1025。


应用从数据库取到id为1025的用户的信息,加载到内存中,进行ORM之类的一系列底层逻辑初始化。

应用根据用户请求进行响应。




3.常见问题

为什么使用JWT

 

4.解决方案

1)前后端分离

以前的传统模式下,后台对应的客户端就是浏览器,就可以使用session+cookies的方式实现登录,但是在前后分离的情况下,后端只负责通过暴露的RestApi提供数据,而页面的渲染、路由都由前端完成。因为rest是无状态的,因此也就不会有session记录到服务器端。

2)传统方式带来的安全性问题

3)性能问题

如果将验证信息保存在数据库中,后端每次都需要根据token查出用户id,这就增加了数据库的查询和存储开销

 

5.编码实战

 

6.扩展思考

 

为什么不推荐用JWT做单点登录我这里却做了单点登录的介绍?

通常因为续签问题导致我们不推荐使用JWT做单点登录,但续签问题可以通过以下的方案进行解决:

每次请求刷新 jwt

只要快要过期的时候刷新jwt

完善 refreshToken

使用 redis 记录独立的过期时间

 

JWT做单点登录的优点:

Session方式来存储用户id,一开始用户的Session只会存储在一台服务器上。对于有多个子域名的站点,每个子域名至少会对应一台不同的服务器,例如:

www.taobao.comnz.taobao.comlogin.taobao.com

所以如果要实现在login.taobao.com登录后,在其他的子域名下依然可以取到Session,这要求我们在多台服务器上同步Session

使用JWT的方式则没有这个问题的存在,因为用户的状态已经被传送到了客户端。因此,我们只需要将含有JWTCookiedomain设置为顶级域名即可,例如

Set-Cookie: jwt=lll.zzz.xxx; HttpOnly; max-age=980000; domain=.taobao.com

 

注意domain必须设置为一个点加顶级域名,即

.taobao.com。这样,taobao.com*.taobao.com就都可以接受到这个Cookie,并获取JWT.


7.参考文献

 

https://blog.csdn.net/congyihao/article/details/70197805

https://blog.csdn.net/achenyuan/article/details/80829401

https://blog.csdn.net/qq_39691226/article/details/80570941

https://blog.csdn.net/weixin_42139757/article/details/80689234

 

8.更多讨论

 

Q1:提问人:周宏浩:

 JWT Token需要持久化在Memcached中吗? 

A1:回答人(何爽):

 这个看业务需求,如果需要长期保存用户的信息那就要持久化,如果只是短时间甚至一次性的用户信息验证那就不需要做持久化。 

 

Q2:提问人:张亚强

 感觉jwt的加密只是又增加了des的加密,造成了双重加密,而不是改变了jwt头部的base64加密吧

A2:回答人(何爽):

 这个确实是改变了头部的加密方式,将头部的base64加密换成了des加密方式,因为des加密在当前是一种几乎不可能被破解的加密方式。

 

Q3:提问人:周宏浩

 服务器端是否应该从JWT中取出userid用于业务查询?

A3:回答人(何爽):

 需要,我们利用JWT的时候就将userid放进了jwt的头部,因此当我们需要用到userid的时候就取出来用于业务的需求。

 

9.鸣谢

感谢张强,翁涵师兄,此教程是在他们之前技术分享的基础上完善而成。

 

10.结束语

今天的分享就到这里啦,欢迎大家点赞、转发、留言、拍砖~

 

 


评论

[真传弟子]JAVA-张帆 发表于 2018-10-09 19:20:08 #1

要弄清楚,为什么jwt比原来的加密方式更安全.安全在哪里.

回复

请您登录 后进行评论