在介绍鉴权方法之前,我们先要了解的是:以及他们之间的关系,有了他们做铺垫,那么我们才能做到从始至终的了解透彻 ~
是指根据声明者所特有的识别信息,确认声明者的身份。
白话文的意思就是:。
比如我们常见的认证技术:
:在信息安全领域是指委派,赋予指定范围的资源操作权限,以便对资源的相关操作。
在现实生活领域例如: 银行卡(由银行派发)、门禁卡(由物业管理处派发)、钥匙(由房东派发),这些都是现实生活中授权的实现方式。
在互联网领域例如: web 服务器的 session 机制、web 浏览器的 cookie 机制、颁发授权令牌(token)等都是一个授权的机制。
在信息安全领域是指对于一个声明者所声明的身份权利,对其所声明的真实性进行鉴别确认的过程。
若从授权出发,则会更加容易理解鉴权。授权和鉴权是两个上下游相匹配的关系,先授权,后鉴权。
在现实生活领域: 门禁卡需要通过门禁卡识别器,银行卡需要通过银行卡识别器;
在互联网领域: 校验 session/cookie/token 的合法性和有效性
是一个承上启下的一个环节,上游它接受授权的输出,校验其真实性后,然后获取权限(permission),这个将会为下一步的权限控制做好准备。
将可执行的操作定义为权限列表,然后判断操作是否允许/禁止
对于权限控制,可以分为两部分进行理解:一个是权限,另一个是控制。权限是抽象的逻辑概念,而控制是具体的实现方式。
在现实生活领域中: 以门禁卡的权限实现为例,一个门禁卡,拥有开公司所有的门的权限;一个门禁卡,拥有管理员角色的权限,因而可以开公司所有的门。
在互联网领域: 通过 web 后端服务,来控制接口访问,允许或拒绝访问请求。
看到这里,我们应该明白了、、和这四个环节是一个、的关系;
前端鉴权
需要说明的是,这四个环节在有些时候会同时发生。例如在下面的几个场景:
“这里提个小问题,供大家思考:认证和鉴权之间的关系?欢迎大家在评论区讨论 ”
既然我们已经了解了他们之间的关系,那么我们应该好好讲讲关于前端鉴权有哪些?以及他们之间存在的差异点又在哪里呢?
在 HTTP 中, 是允许客户端(通常指的就是网页浏览器)在请求时,通过用户提供用户名和密码的方式,实现对用户身份的验证。
“因为几乎所有的线上网站都不会走该认证方案,所以该方案大家了解即可 ”
1.1 认证流程图
HTTP基本鉴权
1.2 认证步骤解析
客户端(如浏览器): 向服务器请求一个,例如字段如下
服务器:客户端你好,这个资源在安全区 里,是受限资源,需要基本认证;
并且向客户端返回 401 状态码(Unauthorized 未被授权的)以及附带提供了一个认证域 要求进行身份验证;
其中 就是验证的模式,而 说明客户端需要输入这个安全域的用户名和密码,而不是其他域的
客户端: 服务器,我已经携带了用户名和密码给你了,你看一下;(注:如客户端是浏览器,那么此时会自动弹出一个弹窗,让用户输入用户名和密码);
输入完用户名和密码后,则客户端将用户名及密码以 base64 加密方式发送给服务器
传送的格式如下 (其中 Basic 内容为:用户名:密码 的 ase64 形式):
服务器: 客户端你好,我已经校验了 字段你的用户名和密码,是正确的,这是你要的资源。
1.3 优点
简单,基本所有流行的浏览器都支持
1.4 缺点
1.5 使用场景
内部网络,或者对安全要求不是很高的网络。
认证是利用服务端的 Session(会话)和 浏览器(客户端) 的 cookie 来实现的前后端通信认证模式。
在理解这句话之前我们先简单了解下 以及 ?
2.1 什么是 cookie
众所周知,(对于事务处理没有记忆能力,每次客户端和服务端会话完成时,服务端不会保存任何会话信息);
所以为了让服务器区分不同的客户端,就必须主动的去维护一个状态,这个状态用于告知服务端前后两个请求是否来自同一浏览器。而这个状态可以通过 去实现。
特点:
2.2 什么是 Session
Session 的抽象概念是会话,是无状态协议通信过程中,为了实现中断/继续操作,将用户和服务器之间的交互进行的一种抽象;
具体来说,是服务器生成的一种 Session 结构,可以通过多种方式保存,如内存、数据库、文件等,大型网站一般有专门的 Session 服务器集群来保存用户会话;
原理流程:
特点:
与 cookie 的差异:
“看到这里可能就有同学想到了, 是不是就是把 存储在了客户端的 中呢? Bingo,的确是这样的,我们接着往下看 ”
2.3 Session-cookie 的认证流程图
Session-cookie的认证流程图
2.4 Session-cookie 认证步骤解析
2.5 Session-cookie 的优点
2.6 Session-cookie 的缺点
2.7 使用场景
现在我们已经得知, 的一些缺点,以及 Session 的维护给服务端造成很大困扰,我们必须找地方存放它,又要考虑分布式的问题,甚至要单独为了它启用一套 Redis 集群。那有没有更好的办法?
那 就应运而生了
3.1 什么是 Token(令牌)
是一个令牌,客户端访问服务器时,验证通过后服务端会为其签发一张令牌,之后,客户端就可以携带令牌访问服务器,服务端只需要验证令牌的有效性即可。
一句话概括;访问资源接口(API)时所需要的资源凭证
一般 Token 的组成:
uid (用户唯一的身份标识) + time (当前时间的时间戳) + sign (签名,Token 的前几位以哈希算法压缩成的一定长度的十六进制字符串)
Token 的认证流程图:
Token的认证流程图
Token 认证步骤解析:
Token 的优点:
Token 的缺点:
3.2 什么是 Refresh Token(刷新 Token)
业务接口用来鉴权的 Token,我们称之为 。
为了安全,我们的 有效期一般设置较短,以避免被盗用。但过短的有效期会造成 经常过期,过期后怎么办呢?
一种办法是:,让用户重新登录获取新 Token,会很麻烦;
另外一种办法是:再来一个 Token,一个专门生成 Access Token 的 Token,我们称为 ;
Refresh Token 的认证流程图:
RefreshToken的认证流程图
Refresh Token 认证步骤解析:
3.3 Token 和 Session-cookie 的区别
和 有很多类似的地方,但是 更像是 的升级改良版。
“如果你的用户数据可能需要和第三方共享,或者允许第三方调用 API 接口,用 Token 。如果永远只是自己的网站,自己的 App,用什么就无所谓了。 ”
通过第三节,我们知道了 的使用方式以及组成,我们不难发现,服务端验证客户端发送过来的 Token 时,还需要查询数据库获取用户基本信息,然后验证 Token 是否有效;
这样每次请求验证都要查询数据库,增加了查库带来的延迟等性能消耗;
那么这时候业界常用的 就应运而生了!!!
4.1 什么是 JWT
是 提出的通过 来实现授权验证的方案;
就是登录成功后将相关用户信息组成 JSON 对象,然后对这个对象进行某种方式的,返回给客户端;客户端在下次请求时带上这个 Token;服务端再收到请求时,其实也就是在校验请求的合法性。
4.2 JWT 的组成
JWT 由三部分组成: 、 和
它是一个很长的字符串,中间用点()分隔成三个部分。列如 :
Header 头部:
在 Header 中通常包含了两部分:
Payload 负载:
它包含一些声明 Claim (实体的描述,通常是一个 User 信息,还包括一些其他的元数据) ,用来存放实际需要传递的数据,JWT 规定了7个官方字段:
除了官方字段,你还可以在这个部分定义私有字段,下面就是一个例子。
Signature 签名
Signature 部分是对前两部分的签名,防止数据篡改。
首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名。
4.3 JWT 的使用方式
客户端收到服务器返回的 JWT,可以储存在 cookie 里面,也可以储存在 localStorage。
此后,客户端每次与服务器通信,都要带上这个 JWT。你可以把它放在 cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP 请求的头信息字段里面。
4.4 JWT 的认证流程图
其实 JWT 的认证流程与 Token 的认证流程差不多,只是不需要再单独去查询数据库查找用户用户;简要概括如下:
JWT的认证流程图的副本
4.5 JWT 的优点
4.6 JWT 的缺点
前面我们已经知道了,在同域下的客户端/服务端认证系统中,通过客户端携带凭证,可以维持一段时间内的登录状态。
但随着企业的发展,一个大型系统里可能包含 n 多子系统,用户在操作不同的系统时,需要多次登录,很麻烦,那么 就可以很好的解决这个问题的,
5.1 同域下的 SSO(主域名相同)
当百度网站存在两个相同主域名下的贴吧子系统 和网盘子系统 时,以下为他们实现 SSO 的步骤:
“其实我们不难发现,这就是我们上面讲的 登录方式;但如果是不同域呢?毕竟不同域之间 cookie 是不共享的,那怎么办? ”
5.2 跨域下的 SSO(主域名不同)
在我们常见的购物网站天猫 (tmall.com) 和 淘宝 (taobao.com) 中,我们只需要登录其中某一个系统,另外一个系统打开后就会默认登录,那么这是怎么做的呢?
那么就有了 ,那么我们先主要说下 的流程;
单点登录下的 CAS 认证流程图:
CAS认证流程图
单点登录下的 CAS 认证步骤详解:
“到这里客户端就可以跟系统 A 愉快的交往啦 ~ ”
“(PS:脚踏两只船,感觉有点渣呀 ~) ”
单点登录下需要注意的点:
在我们实际浏览网站的时候,当我们登录的时候除了输入当前网站的账号密码外,我们还发现可以通过第三方的 QQ 或者 微信登录,那么这又是如何做到了呢,这就要谈到 OAuth 了。
“OAuth 协议又有 1.0 和 2.0 两个版本,2.0 版整个授权验证流程更简单更安全,也是目前最主要的用户身份验证和授权方式。 ”
6.1 什么是 OAuth 2.0?
OAuth 是一个开放标准,允许用户授权第三方网站 (CSDN、思否等) 访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方网站;
常见的提供 OAuth 认证服务的厂商:
简单说,OAuth 就是一种授权机制。数据的所有者告诉系统,同意授权第三方应用进入系统,获取这些数据。系统从而产生一个短期的进入令牌(Token),用来代替密码,供第三方应用使用。
令牌与密码的差异:
与 的作用是一样的,都可以进入系统,但是有三点差异。
OAuth 2.0 对于如何颁发令牌的细节,规定得非常详细。具体来说,一共分成四种授权模式 (Authorization Grant) ,适用于不同的互联网场景。
无论哪个模式都拥有三个必要角色:、、,有的还有,下面简单介绍下四种授权模式。
6.2 授权码模式
方式,指的是第三方应用先申请一个授权码,然后再用该码获取令牌。
这种方式是最常用的流程,安全性也最高,它适用于那些有后端服务的 Web 应用。授权码通过前端传送,令牌则是储存在后端,而且所有与资源服务器的通信都在后端完成。这样的前后端分离,可以避免令牌泄漏。
一句话概括:
授权码模式的步骤详解
客户端:
打开网站 A,点击登录按钮,请求 A 服务,A 服务重定向 (重定向地址如下) 至授权服务器 (如QQ、微信授权服务)。
上面 URL 中, 参数表示要求返回授权码(),参数让 B 知道是谁在请求, 参数是 B 接受或拒绝请求后的跳转网址, 参数表示要求的授权范围(这里是只读)
前端鉴权
授权服务器:
会要求用户登录,然后询问是否同意给予 A 网站授权。用户表示同意,这时 就会跳回 参数指定的网址。跳转时,会传回一个授权码,就像下面这样。
上面 URL 中, 参数就是授权码。
前端鉴权
网站 A 服务器:
拿到授权码以后,就可以向 请求令牌,请求地址如下:
上面 URL 中, 参数和 参数用来让授权服务器 确认 A 的身份( 参数是保密的,因此只能在后端发请求),参数的值是,表示采用的授权方式是授权码, 参数是上一步拿到的授权码, 参数是令牌颁发后的回调网址。
前端鉴权
授权服务器:
收到请求以后,验证通过,就会颁发令牌。具体做法是向 指定的网址,发送一段 JSON 数据。
上面 JSON 数据中, 字段就是令牌,A 网站在后端拿到了,然后返回给客户端即可。
前端鉴权
6.3 隐藏式模式(Implicit Grant)
有些 Web 应用是纯前端应用,没有后端。这时就不能用上面的方式了,必须将令牌储存在前端。OAuth2.0 就规定了第二种方式,允许直接向前端颁发令牌。这种方式没有授权码这个中间步骤,所以称为(授权码)"隐藏式"(implicit)。
一句话概括:。
隐藏式模式的步骤详解
客户端:
打开网站 A,A 网站提供一个链接,要求用户跳转到 ,授权用户数据给 A 网站使用。如下链接:
上面 URL 中,参数为,表示要求直接返回令牌。
授权服务器:
用户跳转到授权服务器,登录后同意给予 A 网站授权。这时,授权服务器就会跳回 参数指定的跳转网址,并且把令牌作为 URL 参数,传给 A 网站。
上面 URL 中,参数就是令牌,A 网站因此直接在前端拿到令牌。
前端鉴权
“注意:
”
6.4 用户名密码式模式(Password Credentials Grant)
如果你高度信任某个应用,OAuth 2.0 也允许用户把用户名和密码,直接告诉该应用。该应用就使用你的密码,申请令牌,这种方式称为"密码式"(password)。
一句话概括:用户在客户端提交账号密码换token,客户端使用token访问资源。
密码式模式的步骤详解
客户端:
A 网站要求用户提供 的用户名和密码。拿到以后,A 就直接向 请求令牌。
上面 URL 中,参数是授权方式,这里的表示"密码式",和是 的用户名和密码。
授权服务器:
验证身份通过后,直接给出令牌。
注意,这时不需要跳转,而是把令牌放在 JSON 数据里面,作为 HTTP 回应,A 网站因此拿到令牌。
“这种方式需要用户给出自己的用户名/密码,显然风险很大,因此只适用于其他授权方式都无法采用的情况,而且必须是用户高度信任的应用。 ”
6.5 客户端模式(Client Credentials Grant)
客户端模式指客户端以自己的名义,而不是以用户的名义,向 进行认证。
主要适用于没有前端的命令行应用。
一句话概括:。
客户端模式的步骤详解
客户端:
客户端向 进行身份认证,并要求一个访问令牌。请求链接地址:
上面 URL 中,参数等于表示采用凭证式,和用来让 确认 A 的身份。
授权服务器:
验证通过以后,直接返回令牌。
“注意:这种方式给出的令牌,是针对第三方应用的,而不是针对用户的,即有可能多个用户共享同一个令牌。 ”
6.5 授权模式选型
按授权需要的多端情况:
按照客户端类型与访问令牌所有者分类:
“上述主要比较浅显的讲解了 OAuth2.0 的基本逻辑,如若想详细深入的了解,可查看官方文档 OAuth或 RFC 6749 亦可查看 OAuth 2.0 概念及授权流程梳理做对比 ”
7.1 什么是联合登陆
指同时包含多种凭证校验的登录服务,同时,也可以理解为使用第三方凭证进行校验的登录服务。
通俗点讲: 对于两个网站 A 和 B,在登录 A 网站的时候用 B 网站的帐号密码,就是联合登录,或者登录 B 网站的时候使用 A 网站的帐号密码,也是联合登录。
这样的概念其实与上面所讲的 OAuth2.0 的 认证方式类似。
最经典的莫过于 APP 内嵌 H5 的使用场景,当用户从 APP 进入内嵌的 H5 时,我们希望 APP 内已登录的用户能够访问到 H5 内受限的资源,而未登录的用户则需要登录后访问。
这里思路主要有两种,一种是原生跳转内嵌 H5 页面时,将登录态 Token 附加在 URL 参数上,另一种则是内嵌 H5 主动通过与原生客户端制定的协议获取应用内的登录状态。
7.2 什么是信任登录
是指所有不需要用户主动参与的登录,例如建立在私有设备与用户之间的绑定关系,凭证就是私有设备的信息,此时不需要用户再提供额外的凭证。信任登录又指用第三方比较成熟的用户库来校验凭证,并登录当前访问的网站。
通俗点讲: 在 A 网站有登录状态的时候,可以直接跳转到 B 网站而不用登录,就是 。
目前比较常见的第三方信任登录帐号如:QQ 号淘宝帐号、支付宝帐号、微博帐号等。
我们不难发现 OAtuth 2.0 其实就是信任登录的缩影,因为正是有了 OAuth,我们的信任登录才得以实现。
— 假设现在产品经理提一个需求:我想要实现用户只能在一个设备上登录,禁止用户重复登录;
— 身为优秀的程序员的我们当然是满足他啦 !!
8.1 什么是唯一登录
唯一登录,指的是禁止多人同时登录同一账号,后者的登录行为,会导致前者掉线。
通俗点讲就是:A 账号在 A 电脑上登录后,A 账号此时又用 B 电脑再次登录,则 A 电脑请求页面时,提示“重新登录”的信息,并跳转到登录页面
8.2 唯一登录流程图
唯一登录流程图的副本
8.3 唯一登录步骤详解
用户在客户端 A 操作:
用户在客户端 B 操作:
突然用户在客户端 B 上开始登录操作,我们会发现,步骤和在客户端A上面的操作几乎是一致的;
只是后端在生成新的 Token 时,要先验证登录状态,然后再生成对应新的 Token;
9.1 什么是扫码登录
扫码登录通常见于移动端 APP 中,很多 PC 端的网站都提供了扫码登录的功能,无需在网页上输入任何账号和密码,只需要让移动端 APP (如微信、淘宝、QQ等等) 中已登录用户主动扫描 ,再确认登录,以使 PC 端的同款应用得以快速登录的方式就是 。
9.2 什么是二维码
又称二维条码,常见的二维码为 QR Code,QR 全称 Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比传统的Bar Code条形码能存更多的信息,也能表示更多的数据类型。
通过上面所述,我们不难发现,扫码登录需要三端 (、、) 来进行配合才能达到登录成功的效果;
9.3 扫码登录的认证流程图
扫码登录的认证流程图的副本
9.4 扫码登录的步骤详解 (待扫码阶段、待确认阶段、已确认阶段)
待扫码阶段:
已扫码待确认阶段:
已确认阶段:
10.1 账号密码登录
大家都知道,最传统的登录方式就是使用账号加密码登录,简单粗暴,一般也不会出现什么问题;
缺点:
直到手机卡的强制实名制才得以解决!
10.2 手机号验证码登录
随着无线互联的发展以及手机卡实名制的推广,手机号俨然已成为特别的身份证明,与账号密码相比,手机号可以更好地验证用户的身份,防止恶意注册。
但是手机号注册还是需要一系列繁琐的操作:输入手机号、等待短信验证码、输入验证码、点击登录。整个流程少说二十秒,而且如果收不到短信,也就登录补了,这类问题有可能导致潜在的用户流失。
从安全角度考虑,还存在验证码泄漏的风险。如果有人知道了你的手机号,并且窃取到了验证码,那他也能登录你的账号了。
所以就有了一键登录操作!
10.3 什么是一键登录
我们想一下,为什么我们需要验证码?验证码的作用就是确定这个手机号是你的,那除了使用短信,是否还有别的方式对手机号进行认证?
于是,就有了咱们的主角一键登录。
短信验证码的作用就是证明当前操作页面的用户与输入手机号的用户为相同的人,那么实际上只要我们能够获取到当前手机使用的手机卡号,直接使用这个号码进行登录,不需要额外的操作,这就是一键登录。
一键登录能不能做,取决于运营商是否开放相关服务;随着运营商开放了相关的服务,我们现在已经能够接入运营商提供的 SDK 并付费使用相关的服务。
一键登录流程图:
一键登录步骤详解:
三大运营商开放平台:
注意:
在认证过程中,需要用户打开蜂窝网络,如果手机设备没有插入 SIM 卡、或者关闭蜂窝网络的情况下,是无法完成认证的。所以就算接入一键登录,还是要兼容传统的登录方式,允许用户在失败的情况下,仍能正常完成登录流程。
在学习了解上面的 10 种鉴权方法后,我们简单概括一下