We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
早前接触和使用了公司内部登录/授权相关服务,现进行知识梳理,方便后续记忆回顾~
最传统的登录方法就是用户名密码校验登录了,流程简单,也有许多细节点,如下:
(HttpOnly = true,Cookie只允许服务端修改,JS 无法操作)
md5(md5(password)+salt)
这种登录模式下,登录态只对当前域名起作用,如当前应用是 app1.oa.com。假设企业内有其它的应用 app2.oa.com、app1.asd.com,那么得另外开发两套登录系统,不能扩展,这显然是不合适的。那么就需要一套多应用共用同一套登录逻辑的系统。
单点登录 (SSO,Single Sign On) 是一种身份验证方法,使用户能够使用一次登录和一组凭据,可以同步登录状态到其他服务。
由账号密码单应用登录流程,我们可以很容易想到,想要共享登录态,只需要客户端能共享 Cookie,服务端能共享 Session 存储就行了。
服务端共享 Session 存储很简单,而客户端,只需要在写入 Cookie 的时候,将 Cookie 写到顶域中去就行了,例如 app1.oa.com,Cookie 写到 oa.com下面,这样 app2.oa.com 也可以读取到 Cookie,然后在后端与 app1.oa.com 使用同一套 Session 存储即可。
同域名下有很多 app 时,可以抽出一个 app,如 sso.oa.com,所有的 appx.oa.com 未登录时都跳转到 sso.oa.com,在 sso.oa.com上验证登录态,再重定向回 appx.oa.com 并种 .oa.com 的 Cookie,这样就实现了同域名下的单点登录。
上面讨论的是同顶域下的情况,假设企业内此时还有一个应用,app1.asd.com,也想用 sso.oa.com 来登录,咋办呢?
现在的问题在于,访问 sso.oa.com 的时候,sso 应用不能往 asd.com下跨域写 Cookie了,难么 sso.oa.com 就得换一种方案来告诉 app1.asd.com,用户是否在 sso 上登录、登录者身份等信息。
Ticket 的实现有很多,例如在 sso.oa.com 中将用户名、有效期等信息对称加密成 Ticket,或者将一条存储记录的索引 id 作为 Ticket,在sso.oa.com/valid 校验成功后返回给 app1.asd.com,这样 asd.com 域下的 app 也能使用 sso.oa.com 作为单点登录服务了。
SSO 在实践的过程中可能会有很多变种,例如访问 sso.oa.com/valid 这一步不再有 appx.asd.com 这些应用服务来实现,而由一个统一的接入层服务来做,并把验证后的结果通过 Header 传递给 appx.asd.com 服务等。
前面说到的是原理的简单理解,真正的业界企业级开源单点登录解决方案叫 CAS(Central Authentication Service,中央认证服务,一种独立开放指令协议)。CAS 是 [耶鲁大学](https://baike.baidu.com/item/耶鲁大学/411935)(Yale University)发起的一个开源项目,旨在为 Web 应用系统提供一种可靠的[单点登录](https://baike.baidu.com/item/单点登录/4940767)方法,CAS 在 2004 年 12 月正式成为 JA-SIG 的一个项目。
CAS 包含两个部分: CAS Server 和 CAS Client。CAS Server 需要独立部署,主要负责对用户的认证工作;CAS Client 负责处理对客户端受保护资源的访问请求,需要登录时,重定向到 CAS Server。CAS 最基本的协议过程:
单说单点登录,使用 OAuth2.0 (Open Authority 2.0) 授权,也是可以做 CAS 解决方案中登录校验的部分的,但是 OAuth2.0 除了做身份校验外,还有个很重要的特性,是可以做细粒度的,用户级别的授权,这个是 CAS 做不到的。
OAuth2.0 将整个系统中的角色分为 HTTP 服务提供商(认证服务器 + 资源服务器 )、第三方应用、用户、用户代理(如浏览器),协议要解决的问题是:HTTP 服务提供商(如微信),授权第三方应用(如某 H5 活动页),在用户代理(如浏览器或微信客户端)中,由用户(经过认证服务器)允许后,从资源服务器中获取某些用户资源(如昵称、头像)。
OAuth 2.0 的运行流程如下图,摘自 [RFC 6749](https://datatracker.ietf.org/doc/html/rfc6749)。
(A)用户打开客户端以后,客户端要求用户给予授权。 (B)用户同意给予客户端授权。 (C)客户端使用上一步获得的授权,向认证服务器申请令牌。 (D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。 (E)客户端使用令牌,向资源服务器申请获取资源。 (F)资源服务器确认令牌无误,同意向客户端开放资源。
(A)用户打开客户端以后,客户端要求用户给予授权。
(B)用户同意给予客户端授权。
(C)客户端使用上一步获得的授权,向认证服务器申请令牌。
(D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。
(E)客户端使用令牌,向资源服务器申请获取资源。
(F)资源服务器确认令牌无误,同意向客户端开放资源。
客户端必须得到用户的授权(authorization grant),才能获得令牌(access token)。OAuth 2.0 定义了四种授权方式。
**简化模式(implicit grant type)**不通过第三方应用程序的服务器,直接在浏览器中向认证服务器申请令牌,跳过了"授权码"这个步骤,因此得名。所有步骤在浏览器中完成,令牌对访问者是可见的,且客户端不需要认证。
它的步骤如下:
(A)客户端将用户导向认证服务器。 (B)用户决定是否给于客户端授权。 (C)假设用户给予授权,认证服务器将用户导向客户端指定的"重定向URI",并在URI的Hash部分包含了访问令牌。 (D)浏览器向资源服务器发出请求,其中不包括上一步收到的Hash值。 (E)资源服务器返回一个网页,其中包含的代码可以获取Hash值中的令牌。 (F)浏览器执行上一步获得的脚本,提取出令牌。 (G)浏览器将令牌发给客户端。
(A)客户端将用户导向认证服务器。
(B)用户决定是否给于客户端授权。
(C)假设用户给予授权,认证服务器将用户导向客户端指定的"重定向URI",并在URI的Hash部分包含了访问令牌。
(D)浏览器向资源服务器发出请求,其中不包括上一步收到的Hash值。
(E)资源服务器返回一个网页,其中包含的代码可以获取Hash值中的令牌。
(F)浏览器执行上一步获得的脚本,提取出令牌。
(G)浏览器将令牌发给客户端。
下面是上面这些步骤所需要的参数。
A步骤中,客户端发出的HTTP请求,包含以下参数:
下面是一个例子。
GET /authorize?response_type=token&client_id=s6BhdRkqt3&state=xyz &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1 Host: server.example.com
C步骤中,认证服务器回应客户端的URI,包含以下参数:
HTTP/1.1 302 Found Location: http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA &state=xyz&token_type=example&expires_in=3600
在上面的例子中,认证服务器用HTTP头信息的Location栏,指定浏览器重定向的网址。注意,在这个网址的Hash部分包含了令牌。
根据上面的D步骤,下一步浏览器会访问Location指定的网址,但是Hash部分不会发送。接下来的E步骤,服务提供商的资源服务器发送过来的代码,会提取出Hash中的令牌。
**密码模式(Resource Owner Password Credentials Grant)**中,用户向客户端提供自己的用户名和密码。客户端使用这些信息,向"服务商提供商"索要授权。
在这种模式中,用户必须把自己的密码给客户端,但是客户端不得储存密码。这通常用在用户对客户端高度信任的情况下,比如客户端是操作系统的一部分,或者由一个著名公司出品。而认证服务器只有在其他授权模式无法执行的情况下,才能考虑使用这种模式。
(A)用户向客户端提供用户名和密码。 (B)客户端将用户名和密码发给认证服务器,向后者请求令牌。 (C)认证服务器确认无误后,向客户端提供访问令牌。
(A)用户向客户端提供用户名和密码。
(B)客户端将用户名和密码发给认证服务器,向后者请求令牌。
(C)认证服务器确认无误后,向客户端提供访问令牌。
B步骤中,客户端发出的HTTP请求,包含以下参数:
POST /token HTTP/1.1 Host: server.example.com Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded grant_type=password&username=johndoe&password=A3ddj3w
C步骤中,认证服务器向客户端发送访问令牌,下面是一个例子。
HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store Pragma: no-cache { "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"example", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter":"example_value" }
上面代码中,各个参数的含义参见《授权码模式》一节。
整个过程中,客户端不得保存用户的密码。
**客户端模式(Client Credentials Grant)**指客户端以自己的名义,而不是以用户的名义,向"服务提供商"进行认证。严格地说,客户端模式并不属于OAuth框架所要解决的问题。在这种模式中,用户直接向客户端注册,客户端以自己的名义要求"服务提供商"提供服务,其实不存在授权问题。
(A)客户端向认证服务器进行身份认证,并要求一个访问令牌。 (B)认证服务器确认无误后,向客户端提供访问令牌。
(A)客户端向认证服务器进行身份认证,并要求一个访问令牌。
(B)认证服务器确认无误后,向客户端提供访问令牌。
granttype:表示授权类型,此处的值固定为"clientcredentials",必选项。
scope:表示权限范围,可选项。
POST /token HTTP/1.1 Host: server.example.com Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
认证服务器必须以某种方式,验证客户端身份。
B步骤中,认证服务器向客户端发送访问令牌,下面是一个例子。
HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store Pragma: no-cache { "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"example", "expires_in":3600, "example_parameter":"example_value" }
Ps: 如果用户访问的时候,客户端的"访问令牌"已经过期,则需要使用"更新令牌"申请一个新的访问令牌。 客户端发出更新令牌的HTTP请求,包含以下参数: granttype:表示使用的授权模式,此处的值固定为"refreshtoken",必选项。 refresh_token:表示早前收到的更新令牌,必选项。 scope:表示申请的授权范围,不可以超出上一次申请的范围,如果省略该参数,则表示与上一次一致。
Ps: 如果用户访问的时候,客户端的"访问令牌"已经过期,则需要使用"更新令牌"申请一个新的访问令牌。
客户端发出更新令牌的HTTP请求,包含以下参数:
Server
Authorization Server
ticket
client_id
client_secret
scope
code
access_token
state
refresh_token
一般情况下我们只会作为用户,或者第三方应用开发者来使用 OAuth2.0 协议,假如我们处于一个需要做 OAuth2.0开放平台的互联网服务团队,或者想深入了解 OAuth2.0 细节的实现,可以基于一个 OAuth2.0 的开源模块实现个认证服务器,并阅读下模块源码,对照着rfc文档参考各个逻辑的实现。例如 [node-oauth2-server模块](https://github.com/oauthjs/node-oauth2-server)
前面提到的各种登录/认证方法,第三方应用的服务器端总是有状态的,需要维护登录用户的 Session 对象。要么前置一个无状态接入层,通过 sessionid hash 到各服务节点,服务节点 LRU 缓存 Session,要么每个节点就得从存储层中读取 Session 信息,请求量大的时候这种 IO 压力不小。
sessionid hash
很自然的想法是,把用户信息存放在客户端去中心化,每次请求的时候随 Cookie 或 Http Header 等渠道发送到服务器上,这样就可以让服务器变成无状态的存在了。JWT 就是实现这种想法的一个标准协议。
JSON Web Token(缩写 JWT),是一种基于 JSON 的、用于在网络上声明某种主张的令牌(token),详见 [rfc7519](https://tools.ietf.org/html/[rfc7519](https://tools.ietf.org/html/rfc7519))。JWT 的原理是,服务器认证以后,生成一个 JSON 对象,发回给用户,就像下面这样。
{ "姓名": "张三", "角色": "管理员", "到期时间": "2018年7月1日0点0分" }
以后,用户与服务端通信的时候,都要发回这个 JSON 对象。服务器完全只靠这个对象认定用户身份。为了防止用户篡改数据,服务器在生成这个对象的时候,会加上签名。
服务器就不保存任何 Session 数据了,也就是说,服务器变成无状态了,从而比较容易实现扩展。
JWT 通常由三部分组成:
写成一行,就是下面的样子。
Header.Payload.Signature
Header 中存储加密算法,Signature是根据 Header 中指定的加密算法,及存在服务端的秘钥计算出来的加密串。具体算法在这里不赘述了,详见 rfc7519
客户端收到服务器返回的 JWT,可以储存在 Cookie 里面,也可以储存在 localStorage。
此后,客户端每次与服务器通信,都要带上这个 JWT。你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP 请求的头信息Authorization字段里面。
Authorization
Authorization: Bearer <token>
另一种做法是,跨域的时候,JWT 就放在 POST 请求的数据体里面。
JWT 默认是不加密,但也是可以加密的。生成原始 Token 以后,可以用密钥再加密一次。
JWT 不加密的情况下,不能将秘密数据写入 JWT。
JWT 不仅可以用于认证,也可以用于交换信息。有效使用 JWT,可以降低服务器查询数据库的次数。
JWT 的最大缺点是,由于服务器不保存 session 状态,因此无法在使用过程中废止某个 token,或者更改 token 的权限。也就是说,一旦 JWT 签发了,在到期之前就会始终有效,除非服务器部署额外的逻辑。
JWT 本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT 的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证。
为了减少盗用,JWT 不应该使用 HTTP 协议明码传输,要使用 HTTPS 协议传输。
理解OAuth 2.0
JSON Web Token 入门教程 - 阮一峰
The text was updated successfully, but these errors were encountered:
No branches or pull requests
早前接触和使用了公司内部登录/授权相关服务,现进行知识梳理,方便后续记忆回顾~
传统用户账号密码登录
最传统的登录方法就是用户名密码校验登录了,流程简单,也有许多细节点,如下:
(HttpOnly = true,Cookie只允许服务端修改,JS 无法操作)
,避免因前端 XSS 漏洞导致 Cookie 泄露md5(md5(password)+salt)
这种登录模式下,登录态只对当前域名起作用,如当前应用是 app1.oa.com。假设企业内有其它的应用 app2.oa.com、app1.asd.com,那么得另外开发两套登录系统,不能扩展,这显然是不合适的。那么就需要一套多应用共用同一套登录逻辑的系统。
单点登录(SSO)
单点登录 (SSO,Single Sign On) 是一种身份验证方法,使用户能够使用一次登录和一组凭据,可以同步登录状态到其他服务。
同顶域单点登录
由账号密码单应用登录流程,我们可以很容易想到,想要共享登录态,只需要客户端能共享 Cookie,服务端能共享 Session 存储就行了。
服务端共享 Session 存储很简单,而客户端,只需要在写入 Cookie 的时候,将 Cookie 写到顶域中去就行了,例如 app1.oa.com,Cookie 写到 oa.com下面,这样 app2.oa.com 也可以读取到 Cookie,然后在后端与 app1.oa.com 使用同一套 Session 存储即可。
同域名下有很多 app 时,可以抽出一个 app,如 sso.oa.com,所有的 appx.oa.com 未登录时都跳转到 sso.oa.com,在 sso.oa.com上验证登录态,再重定向回 appx.oa.com 并种 .oa.com 的 Cookie,这样就实现了同域名下的单点登录。
不同顶域单点登录
上面讨论的是同顶域下的情况,假设企业内此时还有一个应用,app1.asd.com,也想用 sso.oa.com 来登录,咋办呢?
现在的问题在于,访问 sso.oa.com 的时候,sso 应用不能往 asd.com下跨域写 Cookie了,难么 sso.oa.com 就得换一种方案来告诉 app1.asd.com,用户是否在 sso 上登录、登录者身份等信息。
Ticket 的实现有很多,例如在 sso.oa.com 中将用户名、有效期等信息对称加密成 Ticket,或者将一条存储记录的索引 id 作为 Ticket,在sso.oa.com/valid 校验成功后返回给 app1.asd.com,这样 asd.com 域下的 app 也能使用 sso.oa.com 作为单点登录服务了。
SSO 在实践的过程中可能会有很多变种,例如访问 sso.oa.com/valid 这一步不再有 appx.asd.com 这些应用服务来实现,而由一个统一的接入层服务来做,并把验证后的结果通过 Header 传递给 appx.asd.com 服务等。
单点登录实现 - CAS
前面说到的是原理的简单理解,真正的业界企业级开源单点登录解决方案叫 CAS(Central Authentication Service,中央认证服务,一种独立开放指令协议)。CAS 是 [耶鲁大学](https://baike.baidu.com/item/耶鲁大学/411935)(Yale University)发起的一个开源项目,旨在为 Web 应用系统提供一种可靠的[单点登录](https://baike.baidu.com/item/单点登录/4940767)方法,CAS 在 2004 年 12 月正式成为 JA-SIG 的一个项目。
CAS 包含两个部分: CAS Server 和 CAS Client。CAS Server 需要独立部署,主要负责对用户的认证工作;CAS Client 负责处理对客户端受保护资源的访问请求,需要登录时,重定向到 CAS Server。CAS 最基本的协议过程:
OAuth2.0 授权
单说单点登录,使用 OAuth2.0 (Open Authority 2.0) 授权,也是可以做 CAS 解决方案中登录校验的部分的,但是 OAuth2.0 除了做身份校验外,还有个很重要的特性,是可以做细粒度的,用户级别的授权,这个是 CAS 做不到的。
OAuth2.0 将整个系统中的角色分为 HTTP 服务提供商(认证服务器 + 资源服务器 )、第三方应用、用户、用户代理(如浏览器),协议要解决的问题是:HTTP 服务提供商(如微信),授权第三方应用(如某 H5 活动页),在用户代理(如浏览器或微信客户端)中,由用户(经过认证服务器)允许后,从资源服务器中获取某些用户资源(如昵称、头像)。
OAuth 2.0 的运行流程如下图,摘自 [RFC 6749](https://datatracker.ietf.org/doc/html/rfc6749)。
客户端必须得到用户的授权(authorization grant),才能获得令牌(access token)。OAuth 2.0 定义了四种授权方式。
简化模式
**简化模式(implicit grant type)**不通过第三方应用程序的服务器,直接在浏览器中向认证服务器申请令牌,跳过了"授权码"这个步骤,因此得名。所有步骤在浏览器中完成,令牌对访问者是可见的,且客户端不需要认证。
它的步骤如下:
下面是上面这些步骤所需要的参数。
A步骤中,客户端发出的HTTP请求,包含以下参数:
下面是一个例子。
C步骤中,认证服务器回应客户端的URI,包含以下参数:
下面是一个例子。
在上面的例子中,认证服务器用HTTP头信息的Location栏,指定浏览器重定向的网址。注意,在这个网址的Hash部分包含了令牌。
根据上面的D步骤,下一步浏览器会访问Location指定的网址,但是Hash部分不会发送。接下来的E步骤,服务提供商的资源服务器发送过来的代码,会提取出Hash中的令牌。
密码模式
**密码模式(Resource Owner Password Credentials Grant)**中,用户向客户端提供自己的用户名和密码。客户端使用这些信息,向"服务商提供商"索要授权。
在这种模式中,用户必须把自己的密码给客户端,但是客户端不得储存密码。这通常用在用户对客户端高度信任的情况下,比如客户端是操作系统的一部分,或者由一个著名公司出品。而认证服务器只有在其他授权模式无法执行的情况下,才能考虑使用这种模式。
它的步骤如下:
B步骤中,客户端发出的HTTP请求,包含以下参数:
下面是一个例子。
C步骤中,认证服务器向客户端发送访问令牌,下面是一个例子。
上面代码中,各个参数的含义参见《授权码模式》一节。
整个过程中,客户端不得保存用户的密码。
客户端模式
**客户端模式(Client Credentials Grant)**指客户端以自己的名义,而不是以用户的名义,向"服务提供商"进行认证。严格地说,客户端模式并不属于OAuth框架所要解决的问题。在这种模式中,用户直接向客户端注册,客户端以自己的名义要求"服务提供商"提供服务,其实不存在授权问题。
它的步骤如下:
A步骤中,客户端发出的HTTP请求,包含以下参数:
granttype:表示授权类型,此处的值固定为"clientcredentials",必选项。
scope:表示权限范围,可选项。
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
认证服务器必须以某种方式,验证客户端身份。
B步骤中,认证服务器向客户端发送访问令牌,下面是一个例子。
上面代码中,各个参数的含义参见《授权码模式》一节。
OAuth2.0 扩展
CAS 与 OAuth2 对比
Server
,OAuth2.0 场景中资源是在于Authorization Server
ticket
只能使用一次ticket
有效期设置,条件内越短越安全ticket
生成需要足够随机,如果被攻击者猜出规律,则可以计算出下一个ticket值client_id
和client_secret
,同时也可以对scope
和域名进行匹配校验code
有效期较短,code
只能被使用一次,使用第二次会使第一次获得的access_token
失效。access_token
通过后端方式接口获取和接口使用,不会展示在前端,暴露可能性低access_token
只有scope
资源使用权限,并不会影响到其他部分state
参数可以有效防止csrf攻击refresh_token
后端更新 token,无需再走一遍完整流程。OAuth2.0 服务开发
一般情况下我们只会作为用户,或者第三方应用开发者来使用 OAuth2.0 协议,假如我们处于一个需要做 OAuth2.0开放平台的互联网服务团队,或者想深入了解 OAuth2.0 细节的实现,可以基于一个 OAuth2.0 的开源模块实现个认证服务器,并阅读下模块源码,对照着rfc文档参考各个逻辑的实现。例如 [node-oauth2-server模块](https://github.com/oauthjs/node-oauth2-server)
JSON Web Token (JWT)
前面提到的各种登录/认证方法,第三方应用的服务器端总是有状态的,需要维护登录用户的 Session 对象。要么前置一个无状态接入层,通过
sessionid hash
到各服务节点,服务节点 LRU 缓存 Session,要么每个节点就得从存储层中读取 Session 信息,请求量大的时候这种 IO 压力不小。很自然的想法是,把用户信息存放在客户端去中心化,每次请求的时候随 Cookie 或 Http Header 等渠道发送到服务器上,这样就可以让服务器变成无状态的存在了。JWT 就是实现这种想法的一个标准协议。
JSON Web Token(缩写 JWT),是一种基于 JSON 的、用于在网络上声明某种主张的令牌(token),详见 [rfc7519](https://tools.ietf.org/html/[rfc7519](https://tools.ietf.org/html/rfc7519))。JWT 的原理是,服务器认证以后,生成一个 JSON 对象,发回给用户,就像下面这样。
以后,用户与服务端通信的时候,都要发回这个 JSON 对象。服务器完全只靠这个对象认定用户身份。为了防止用户篡改数据,服务器在生成这个对象的时候,会加上签名。
服务器就不保存任何 Session 数据了,也就是说,服务器变成无状态了,从而比较容易实现扩展。
JWT 的数据结构
JWT 通常由三部分组成:
写成一行,就是下面的样子。
Header 中存储加密算法,Signature是根据 Header 中指定的加密算法,及存在服务端的秘钥计算出来的加密串。具体算法在这里不赘述了,详见 rfc7519
JWT 的使用方式
客户端收到服务器返回的 JWT,可以储存在 Cookie 里面,也可以储存在 localStorage。
此后,客户端每次与服务器通信,都要带上这个 JWT。你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP 请求的头信息
Authorization
字段里面。另一种做法是,跨域的时候,JWT 就放在 POST 请求的数据体里面。
JWT 的几个特点
JWT 默认是不加密,但也是可以加密的。生成原始 Token 以后,可以用密钥再加密一次。
JWT 不加密的情况下,不能将秘密数据写入 JWT。
JWT 不仅可以用于认证,也可以用于交换信息。有效使用 JWT,可以降低服务器查询数据库的次数。
JWT 的最大缺点是,由于服务器不保存 session 状态,因此无法在使用过程中废止某个 token,或者更改 token 的权限。也就是说,一旦 JWT 签发了,在到期之前就会始终有效,除非服务器部署额外的逻辑。
JWT 本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT 的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证。
为了减少盗用,JWT 不应该使用 HTTP 协议明码传输,要使用 HTTPS 协议传输。
References
理解OAuth 2.0
JSON Web Token 入门教程 - 阮一峰
The text was updated successfully, but these errors were encountered: