【译】JWT(JSON Web Token) 入门指南

原文地址:https://blog.angular-university.io/angular-jwt/

这篇文章是两篇手把手教你如何在Angular应用(也适用于企业级应用)中实现基于JWT的认证方式的文章中的第一篇。

本篇文章的首要目标是详细学习JWTs如何运行,包括它在web应用中怎么用来做用户认证和session管理的。

第二篇文章中,我们会介绍基于JWT的认证系统是在特定的Angular应用中可以如何实现,但是这篇文章仅仅是介绍JWTs。

为什么要深入了解JWT

全面详细了解JWT是为了一下几点:

一个基于JWT实现的认证系统的解决方案

各种各样的使用差错技巧:了解错误信息、堆栈等

了解各种第三方的库和他们的文档

设计一个内部的认证系统的解决方案

选择和配置一个第三方的认证服务

在选择使用基于JWT的认证解决方案之后,也会有涉及客户端一些代码的编写,当然服务端也需要。

这篇文档的最后,你会深入的理解JWT最原始的加密技术,这些技术也会应用在其他安全场合。

你会知道为什么和什么时候会使用JWT,你也会知道JWT的格式,甚至知道如何排查签名的问题,并知晓一些在网上使用的小工具。

使用这些小工具你可以自己排查无数关于JWT的问题。废话不多说,我们开始吧!

为什么使用JWTs

JWTs 相比于使用内存产生的随机token的用户session管理机制的最大优势在于,它可以把验证逻辑委托给第三方的服务,他们可能是如下几种:

集中式的自定义开发的认证服务器

典型的可以支持JWTs的商业产品,比如LDAP

完全外部的第三方认证提供商,比如 Autho

外部认证服务器可以完全和应用服务器分开,而且不必在网络上分享secret key,也就是说我们的应用服务器没有意外丢失secret key的可能。

另外,应用服务器和认证服务器无需保持连接也可以进行认证工作。

更好的一点是,应用服务器无需在内存中记住token,也就是说服务是无状态的。认证服务器可以产生token,传送给应用服务器,然后立刻删除。

还有一点是,应用服务器在数据库层面也无需存储口令的摘要信息。存储的东西越少,安全相关的丢失bug就相应减少了。

在这里你可以会想:对于内部的应用服务器,JWTs是一个好的解决方案吗?当然,在这篇文章的最后一部分,我会讲关于JWTs认证方面的一些典型企业级应用场景。

目录

在这篇文章中将会涵盖以下一个内容:

JWTs是什么

JWT的一些网上校验工具

jwt 的格式

JWTs 的层次结构:头、载体、签名

Base64Url (对比 Base64)

JWTs的用户会话管理:主体和过期

HS256 JWT 签名 - 是如何工作的

数字签名

哈希方法和 SHA-256

RS256 JWT 签名 - 让我们聊聊公钥加密

RS256 vs HS256 - 哪一个更好

JWKS(Json web key set)Endpoints

如何实现 JWT 周期循环签名

企业级 JWTs

总结和结论

JWTs是什么

JWT 仅仅是一个代用特殊信息的Json载体。JWTs的主要目的是为了确定它是否有效,而确定它是否有效我们仅仅只需要看它所携带的token。

我们不需要和第三方服务通信或是把JWTs保存在内存中,就可以保证它携带的信息是有效的--这是因为他们携带了信息认证码,即MAC。

JWT 由三部分组成:头、载体和签名。我们一个个讲,首先讲讲载体。

如何描述JWT 载体

JWT 的载体是一个 JavaScript 对象。这里有一个有效的载体对象:

{ "name":"john doe", "email":"john@johndoe.com", "admin": true }

在这个例子中,载体包含了一个特定用户的身份信息,但是通常来说,载体可以是其他一些信息,比如一笔银行转账信息。

关于载体内容没有严格的约束,但是你一定要知道JWT是没有被加密的。所以拦截到token后,其中的任何信息都是可读的。

因此一定不要在载体中放入可以被攻击者直接获得的用户信息。

JWT Headers - 为什么他们必要

载体中的内容通过签名信息被接受者验证。但是签名是多种多样的,接受者首先需要知道要去找哪种类型的签名方式。

这个关于token类型的元信息被分开存储,它也是一个JavaScript对象,和载体一起被发送出去。

这个分开存储的json对象即JWT的头,这里有一个有效的头示例:

{ "alg":"RS256", "typ":"JWT" }

从上面我们可以看到JWT header 也是一个简单的JavaScript对象,上面的签名算法是RS256。

我们后面再聊聊签名的类型,现在我们专注于了解签名在认证中的作用。

JWT 签名 - 认证怎么使用

上一部分讲的签名是消息认证码(MAC)。JWT 的签名只能从载体(加上头)和一个特定的秘钥产生。

下面是签名怎么保证认证的步骤:

用户提交用户名和口令到认证服务器,这个服务器可能是我们的服务器,更典型的应用时一个分开的服务

认证服务器校验通过后,产生token,这个token的载体中包含了用户的身份信息和过期时间

认证服务器用秘钥把token头和载体签名后传递给用户浏览器(接下来会详细讲如何使用签名)

浏览器携带签名后的JWT和HTTP请求一起发送给应用服务器

签名后的JWT是一个更有效的临时用户凭据,用于替代用户名密码这个永久用户凭证。

接下来,是应用服务器是怎么处理JWT token的:

应用服务器检查JWT签名,确认它持有秘钥的人对这个载体的签名

载体表示了特定的用户

只有认证服务器才有秘钥,并且认证服务器只给输入了正确密码的用户发送token

因此应用服务器可以确定token的持有者是经过认证的用户,也就是输入了正确密码的用户

应用服务器对这个用户处理请求

攻击者模拟用户访问应用服务器只有两种,要么是盗了用户的用户名和密码,要么是知道了认证服务器的私钥。

到这里我们可以看到,签名是JWT的关键部分。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwfsys.html