關於前端鑑權這塊,Token、Cookie、Session、JWT、單一登入、掃碼登入、一鍵登入是什麼意思?分別有什麼作用?你一般是怎麼做的?以及你是怎麼儲存的呢?那你又是怎麼保證它的安全的呢?以下這篇文章教你搞定前後端所有鑑權方案,讓你不再迷惘!
還記得之前在面試的時候,有一位面試官就問了,關於前端鑑權這塊,Token、Cookie、Session、JWT、單點登入
是什麼?有什麼作用?你一般是怎麼做的?以及你是怎麼儲存的呢?那你又是怎麼保證它
的安全的呢?
一頓連問下來,我是焦頭又爛額,欲言而又止.......
其實鑑權的方法有很多,下面我總結了常用的10種鑑權方法
,那麼哪一種是最適合你的系統呢?哪一種又最安全呢?
那就讓我們從下文慢慢探索尋找答案 ~
在介紹鑑權方法之前,我們先要了解的是:什麼是認證、授權、鑑權、權限控制
以及他們之間的關係,有了他們做鋪墊,那麼我們才能做到從頭到尾的了解透徹~
認證(Identification)
是指根據宣告者所特有的識別訊息,確認宣告者的身分。
白話文的意思是:你需要用身分證證明你自己是你自己
。
例如我們常見的認證技術:
授權(Authorization)
: 在資訊安全領域是指資源擁有者
委派執行者
,賦予執行者
指定範圍的資源操作權限,以便對資源的相關操作。
在現實生活領域例如:銀行卡(由銀行發放)、門禁卡(由物業管理處派發)、鑰匙(由房東派發),這些都是現實生活中授權的實現方式。
在網際網路領域例如:web 伺服器的 session 機制、web 瀏覽器的 cookie 機制、頒發授權令牌(token)等都是一個授權的機制。
鑑權(Authentication)
在資訊安全領域是指對於一個宣告者所宣告的身分權利,對其所宣告的真實性進行鑑別確認的過程。
若從授權出發,則會更容易理解鑑權。授權和鑑權是兩個上下游相符的關係,先授權,後鑑權。
在現實生活領域:門禁卡需要通過門禁卡識別器,銀行卡需要通過銀行卡識別器;
##在互聯網領域:校驗session/cookie/token 的合法性和有效性
鑑權是一個承上啟動的一個環節,上游它接受授權的輸出,校驗其真實性後,然後取得權限(permission),這個將會為下一步的權限控製做好準備。
權限控制(Access/Permission Control)將可執行的操作定義為權限列表,然後判斷操作是否允許/禁止
在現實生活領域中:以門禁卡的權限實現為例,一個門禁卡,擁有開公司所有的門的權限;一個門禁卡,擁有管理員角色的權限,因而可以開公司所有的門。
在互聯網領域:透過 web 後端服務,來控制介面訪問,允許或拒絕存取請求。
認證、
授權、
鑑權和
權限控制#這四個環節是一個
前後依序發生、
上下游的關係;
這裡提個小問題,供大家思考:認證和鑑權之間的關係?歡迎大家在留言區討論
既然我們已經了解了他們之間的關係,那麼我們應該好好講講關於前端鑑權有哪些?以及他們之間存在的差異點又在哪裡呢?
在HTTP 中,基本認證方案(Basic Access Authentication)
是允許客戶端(通常指的就是網頁瀏覽器)在請求時,透過使用者提供使用者名稱和密碼的方式,實現使用者身分的驗證。
因為幾乎所有的線上網站都不會走該認證方案,所以該方案大家了解即可
1.1認證流程圖
#1.2 認證步驟解析
客戶端(如瀏覽器):向伺服器請求一個
受限的清單資料或資源,例如欄位如下
GET /list/ HTTP/1.1 Host: www.baidu.com Authorization: Basic aHR0cHdhdGNoOmY=
伺服器:客戶端你好,這個資源在安全區baidu.com
裡,是受限資源,需要基本認證;並且向客戶端回傳401狀態碼(Unauthorized 未被授權的)以及附帶提供了一個認證域www-Authenticate: Basic realm=”baidu.com”要求進行身份驗證;
其中realm="baidu.com"則表示客戶端需要輸入這個安全域的使用者名稱和密碼,而不是其他網域的
HTTP/1.1 401 Unauthorized www-Authenticate: Basic realm= "baidu.com"
輸入使用者名稱及密碼後,則客戶端將使用者名稱及密碼以Base64 加密方式傳送至伺服器傳送的格式如下(其中Basic 內容為:使用者名稱:密碼 的ase64 形式
):GET /list/ HTTP/1.1 Authorization: Basic Ksid2FuZzp3YW5n==
伺服器:客戶端你好,我已經校驗了Authorization
欄位你的使用者名稱和密碼,是正確的,這是你要的資源。HTTP/1.1 200 OK ...
1.3 優點
由於是基於HTTP 傳輸,所以它在網路上幾乎是裸奔的,雖然它使用了Base64 來編碼,但這個編碼很容易就可以解碼出來。即使認證內容無法被解碼為原始的使用者名稱和密碼也是不安全的,惡意使用者可以再取得了認證內容後使用其不斷的享伺服器發起請求,這就是所謂的重播攻擊。
1.5 使用場景
2. Session-Cookie 識別碼
Session-Cookie
認證是利用服務端的Session(會話)和瀏覽器(客戶端) 的Cookie 來實現的前後端通訊認證模式。
在理解這句話之前我們先簡單了解下
什麼是 Cookie
什麼是 Session?
######2.1 什麼是Cookie#############眾所周知,###HTTP 是無狀態的協定###(對於交易處理沒有記憶能力,每次客戶端和服務端會話完成時,服務端不會保存任何會話資訊);######所以為了讓伺服器區分不同的客戶端,就必須主動的去維護一個狀態,這個狀態用於告知服務端前後兩個請求是否來自同一瀏覽器。而這個狀態可以透過 ###Cookie### 去實現。 #########特點:#######2.2 什麼是Session
Session 的抽象概念是會話,在無狀態協定通訊過程中,為了實現中斷/繼續操作,將使用者和伺服器之間的互動進行的一種抽象;
具體來說,是伺服器產生的一種Session 結構,可以透過多種方式保存,如記憶體、資料庫、檔案等,大型網站一般有專門的Session 伺服器叢集來保存使用者會話;
##原理流程:
客戶端:使用者首次向伺服器發送請求;
#伺服器:接收到資料並自動為該使用者創建特定的Session / Session ID,來標識使用者並追蹤使用者目前的會話過程;
#客戶端:瀏覽器收到回應以取得會話訊息,並且會在下次要求時帶上Session / Session ID;
伺服器:伺服器提取後會與本機儲存的Session ID進行比較找到該特定使用者的會話,進而取得會話狀態;
Session 保存在伺服器上;
是不是就是把2.3 Session-Cookie 的認證流程圖Session
,的確是這樣的,我們接著往下看儲存在了客戶端的
Cookie中呢?
Bingo
2.4 Session-Cookie 認證步驟解析
session_id(通常稱為sid),並在回應頭
Set-Cookie中設定這個唯一識別碼;
註:可以使用簽章對
進行加密處理,服務端會根據對應的secret
金鑰進行解密(非必須步驟)
sid儲存在本機Cookie 中,瀏覽器在下次HTTP 請求時請求頭會自動附帶上該網域下的Cookie 資訊;
sid,然後根據這個sid去找服務端保存的該客戶端的
sid,然後判斷該請求是否合法;
#Cookie 簡單易用
2.7 使用場景
2.8 前端常用的Session 函式庫推薦
#現在我們已經得知,Session-Cookie
的一些缺點,以及Session 的維護對服務端造成很大困擾,我們必須找地方存放它,又要考慮分散式的問題,甚至要單獨為了它啟用一套Redis 叢集。那有沒有更好的辦法?
那Token
就應運而生了
3.1 什麼是Token(令牌)
Token
是一個令牌,客戶端存取伺服器時,驗證透過後服務端會為其簽發一張令牌,之後,客戶端就可以攜帶令牌存取伺服器,服務端只需要驗證令牌的有效性即可。一句話概括;存取資源介面(API)時所需要的資源憑證
一般Token 的組成:uid
(目前時間的時間戳記)sign(簽名,Token 的前幾位被雜湊演算法壓縮成的一定長度的十六進位字串)
Token 認證步驟解析:
客戶端:輸入使用者名稱和密碼請求登入校驗;
收到請求,去驗證使用者名稱與密碼;驗證成功後,服務端會簽發一個Token 並把這個Token 傳送給客戶端;
收到Token 以後需要把它儲存起來,web 端通常會放在localStorage 或Cookie 中,行動端原生APP 一般儲存在本機快取中;
Token 機制在服務端不需要儲存會話( Session)訊息,因為Token 本身包含了其所標識使用者的相關訊息,這有利於在多個服務間共享使用者狀態##支援APP 行動端裝置;
sid更大,消耗更多流量,擠佔更多寬頻效能問題:
雖然驗證Token 時不用再去存取資料庫或遠端服務進行權限校驗,但需要對Token 加解密等操作,所以會更耗效能;有效期限短:
Refresh Token;
3.2 什麼是Refresh Token(刷新Token )
另外一种办法是:再来一个 Token,一个专门生成 Access Token 的 Token,我们称为Refresh Token
;
Refresh Token 的认证流程图:
Refresh Token 认证步骤解析:
客户端:输入用户名和密码请求登录校验;
服务端:收到请求,验证用户名与密码;验证成功后,服务端会签发一个Access Token
和Refresh Token
并返回给客户端;
客户端:把Access Token
和Refresh Token
存储在本地;
客户端发送请求:请求数据时,携带Access Token
传输给服务端;
服务端:
客户端( Access Token 已过期):则重新传输 Refresh Token 给服务端;
服务端( Access Token 已过期):验证 Refresh Token ,验证成功后返回新的 Access Token 给客户端;
客户端:重新携带新的 Access Token 请求接口;
3.3 Token 和 Session-Cookie 的区别
Session-Cookie
和Token
有很多类似的地方,但是Token
更像是Session-Cookie
的升级改良版。
如果你的用户数据可能需要和第三方共享,或者允许第三方调用 API 接口,用 Token 。如果永远只是自己的网站,自己的 App,用什么就无所谓了。
通过第三节,我们知道了Token
的使用方式以及组成,我们不难发现,服务端验证客户端发送过来的 Token 时,还需要查询数据库获取用户基本信息,然后验证 Token 是否有效;
这样每次请求验证都要查询数据库,增加了查库带来的延迟等性能消耗;
那么这时候业界常用的JWT
就应运而生了!!!
4.1 什么是 JWT
JWT
是Auth0
提出的通过对 JSON 进行加密签名
来实现授权验证的方案;
就是登录成功后将相关用户信息组成 JSON 对象,然后对这个对象进行某种方式的加密
,返回给客户端; 客户端在下次请求时带上这个 Token; 服务端再收到请求时校验 token 合法性
,其实也就是在校验请求的合法性。
4.2 JWT 的组成
JWT 由三部分组成:Header 头部
、Payload 负载
和Signature 签名
它是一个很长的字符串,中间用点(.
)分隔成三个部分。列如 :
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Header 头部:
在 Header 中通常包含了两部分:
{ "alg": "HS256", "typ": "JWT" }
Payload 负载:
它包含一些声明 Claim (实体的描述,通常是一个 User 信息,还包括一些其他的元数据) ,用来存放实际需要传递的数据,JWT 规定了7个官方字段:
除了官方字段,你还可以在这个部分定义私有字段,下面就是一个例子。
{ "sub": "1234567890", "name": "John Doe", "admin": true }
Signature 签名
Signature 部分是对前两部分的签名,防止数据篡改。
首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名。
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
4.3 JWT 的使用方式
客户端收到服务器返回的 JWT,可以储存在 Cookie 里面,也可以储存在 localStorage。
此后,客户端每次与服务器通信,都要带上这个 JWT。你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP 请求的头信息Authorization
字段里面。
Authorization: Bearer
4.4 JWT 的认证流程图
其实 JWT 的认证流程与 Token 的认证流程差不多,只是不需要再单独去查询数据库查找用户用户;简要概括如下:
4.5 JWT 的优点
4.6 JWT 的缺点
4.7 前端常用的 JWT 库推荐
前面我们已经知道了,在同域下的客户端/服务端认证系统中,通过客户端携带凭证,可以维持一段时间内的登录状态。
但随着企业的发展,一个大型系统里可能包含 n 多子系统,用户在操作不同的系统时,需要多次登录,很麻烦,那么单点登录(SSO)
就可以很好的解决这个问题的,在多个应用系统中,只需要登录一次,就可以访问其他相互信任的应用系统。
5.1 同域下的 SSO(主域名相同)
当百度网站存在两个相同主域名下的贴吧子系统tieba.baidu.com
和网盘子系统pan.baidu.com
时,以下为他们实现 SSO 的步骤:
客户端:用户访问某个子系统时(例如tieba.baidu.com
),如果没有登录,则跳转至 SSO 认证中心提供的登录页面进行登录;
服务端:登录认证后,服务端把登录用户的信息存储于 Session 中,并且附加在响应头的Set-Cookie
字段中,设置 Cookie 的 Domain 为.baidu.com
;
客户端:再次发送请求时,携带主域名 Domain 下的 Cookie 给服务器,此时服务端就可以通过该 Cookie 来验证登录状态了;
其实我们不难发现,这就是我们上面讲的
Session-Cookie 认证
登录方式; 但如果是不同域呢?毕竟不同域之间 Cookie 是不共享的,那怎么办?
5.2 跨域下的 SSO(主域名不同)
在我們常見的購物網站天貓(tmall.com) 和淘寶(taobao.com) 中,我們只需要登錄其中某一個系統,另外一個系統打開後就會默認登錄,那麼這是怎麼做的呢?
那麼就有了CAS(Central Authentication Service)中央授權服務
,那麼我們先主要說下CAS
的流程;
單一登入下的CAS 認證流程圖:
#單一登入下的CAS 認證步驟詳解:
客戶端:開始存取系統A;
#系統A:發現使用者未登錄,重定向至CAS 認證服務(sso.com),同時URL 位址參數攜帶登入成功後回跳到系統A 的頁面連結(sso.com/login?redir…
CAS 認證服務:發現請求Cookie 中沒有攜帶登入的票據憑證(TGC),所以CAS 認證服務判定使用者處於未登入
狀態,重定向使用者頁面至CAS 的登入介面,使用者在CAS 的登入頁面上進行登入操作。
用戶端:輸入使用者名稱密碼進行CAS 系統認證;
CAS 認證服務:校驗使用者訊息,並且產生TGC
放入自己的Session 中,同時以Set-Cookie 形式寫入Domain 為sso.com
的網域下;同時產生一個授權令牌ST (Service Ticket)
,然後重定向至系統A 的位址,重定向的位址包含產生的ST(重定向位址:www.taobao.com?token=ST-345678)
系統A:拿著ST 向CAS 認證服務發送請求, CAS 認證服務驗證票據(ST) 的有效性。驗證成功後,系統A 知道使用者已經在CAS 登入了(其中的ST 可以儲存到Cookie 或本地中),系統A 伺服器使用該票據(ST) 建立與使用者的會話,稱為局部會話,返回受保護資源;
到這裡客戶端就可以跟系統A 愉快的交往啦~
(PS:腳踏兩艘船,感覺有點渣呀~)
如圖流程所示,我們發現
CAS 認證服務
:登入接口,用於登入中央授權服務
:登出接口,用於從中央授權服務中登出
:用於驗證使用者是否登入中央授權服務
TGT(Ticket Grangting Ticket)
#在我們實際瀏覽網站的時候,當我們登入的時候除了輸入當前網站的帳號密碼外,我們還發現可以透過第三方的QQ 或微信登錄,那麼這又是如何做到了呢,這就要談到
OAuth 协议又有 1.0 和 2.0 两个版本,2.0 版整个授权验证流程更简单更安全,也是目前最主要的用户身份验证和授权方式。
6.1 什么是 OAuth 2.0?
OAuth是一个开放标准,允许用户授权第三方网站 (CSDN、思否等) 访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方网站;
常见的提供 OAuth 认证服务的厂商:支付宝、QQ、微信、微博
简单说,OAuth 就是一种授权机制。数据的所有者告诉系统,同意授权第三方应用进入系统,获取这些数据。系统从而产生一个短期的进入令牌(Token),用来代替密码,供第三方应用使用。
令牌与密码的差异:
令牌(Token)
与密码(Password)
的作用是一样的,都可以进入系统,但是有三点差异。
令牌是短期的,到期会自动失效:用户自己无法修改。密码一般长期有效,用户不修改,就不会发生变化。
令牌可以被数据所有者撤销,会立即失效。
令牌有权限范围(scope):对于网络服务来说,只读令牌就比读写令牌更安全。密码一般是完整权限。
OAuth 2.0 对于如何颁发令牌的细节,规定得非常详细。具体来说,一共分成四种授权模式(Authorization Grant),适用于不同的互联网场景。
无论哪个模式都拥有三个必要角色:客户端
、授权服务器
、资源服务器
,有的还有用户(资源拥有者)
,下面简单介绍下四种授权模式。
6.2 授权码模式
授权码(Authorization Code Grant)
方式,指的是第三方应用先申请一个授权码,然后再用该码获取令牌。
这种方式是最常用的流程,安全性也最高,它适用于那些有后端服务的 Web 应用。授权码通过前端传送,令牌则是储存在后端,而且所有与资源服务器的通信都在后端完成。这样的前后端分离,可以避免令牌泄漏。
一句话概括:客户端换取授权码,客户端使用授权码换token,客户端使用token访问资源
客户端:
打开网站 A,点击登录按钮,请求 A 服务,A 服务重定向 (重定向地址如下) 至授权服务器 (如QQ、微信授权服务)。
https://qq.com/oauth/authorize? response_type=code& client_id=CLIENT_ID& redirect_uri=CALLBACK_URL& scope=read
上面 URL 中,response_type
参数表示要求返回授权码(code
),client_id
参数让 B 知道是谁在请求,redirect_uri
参数是 B 接受或拒绝请求后的跳转网址,scope
参数表示要求的授权范围(这里是只读)
授权服务器:
授权服务网站
会要求用户登录,然后询问是否同意给予 A 网站授权。用户表示同意,这时授权服务网站
就会跳回redirect_uri
参数指定的网址。跳转时,会传回一个授权码,就像下面这样。
https://a.com/callback?code=AUTHORIZATION_CODE
上面 URL 中,code
参数就是授权码。
网站 A 服务器:
拿到授权码以后,就可以向授权服务器 (qq.com)
请求令牌,请求地址如下:
https://qq.com/oauth/token? client_id=CLIENT_ID& client_secret=CLIENT_SECRET& grant_type=authorization_code& code=AUTHORIZATION_CODE& redirect_uri=CALLBACK_URL
上面 URL 中,client_id
参数和client_secret
参数用来让授权服务器 确认 A 的身份(client_secret
参数是保密的,因此只能在后端发请求),grant_type
参数的值是AUTHORIZATION_CODE
,表示采用的授权方式是授权码,code
参数是上一步拿到的授权码,redirect_uri
参数是令牌颁发后的回调网址。
授权服务器:
收到请求以后,验证通过,就会颁发令牌。具体做法是向redirect_uri
指定的网址,发送一段 JSON 数据。
{ "access_token":"ACCESS_TOKEN", "token_type":"bearer", "expires_in":2592000, "refresh_token":"REFRESH_TOKEN", "scope":"read", "uid":100101, "info":{...} }
上面 JSON 数据中,access_token
字段就是令牌,A 网站在后端拿到了,然后返回给客户端即可。
6.3 隐藏式模式(Implicit Grant)
有些 Web 应用是纯前端应用,没有后端。这时就不能用上面的方式了,必须将令牌储存在前端。OAuth2.0 就规定了第二种方式,允许直接向前端颁发令牌。这种方式没有授权码这个中间步骤,所以称为(授权码)"隐藏式"(implicit)。
一句话概括:客户端让用户登录授权服务器换token,客户端使用token访问资源
。
客户端:
打开网站 A,A 网站提供一个链接,要求用户跳转到授权服务器
,授权用户数据给 A 网站使用。如下链接:
https://qq.com/oauth/authorize? response_type=token& client_id=CLIENT_ID& redirect_uri=CALLBACK_URL& scope=read
上面 URL 中,response_type
参数为token
,表示要求直接返回令牌。
授权服务器:
用户跳转到授权服务器,登录后同意给予 A 网站授权。这时,授权服务器就会跳回redirect_uri
参数指定的跳转网址,并且把令牌作为 URL 参数,传给 A 网站。
https://a.com/callback#token=ACCESS_TOKEN
上面 URL 中,token
参数就是令牌,A 网站因此直接在前端拿到令牌。
注意:
令牌的位置是 URL 锚点(fragment),而不是查询字符串(querystring),这是因为 OAuth 2.0 允许跳转网址是 HTTP 协议,因此存在"中间人攻击"的风险,而浏览器跳转时,锚点不会发到服务器,就减少了泄漏令牌的风险。
这种方式把令牌直接传给前端,是很不安全的。因此,只能用于一些安全要求不高的场景,并且令牌的有效期必须非常短,通常就是会话期间(session)有效,浏览器关掉,令牌就失效了。
6.4 用户名密码式模式(Password Credentials Grant)
如果你高度信任某个应用,OAuth 2.0 也允许用户把用户名和密码,直接告诉该应用。该应用就使用你的密码,申请令牌,这种方式称为"密码式"(password)。
一句话概括:用户在客户端提交账号密码换token,客户端使用token访问资源。
客户端:
A 网站要求用户提供授权服务器(qq.com)
的用户名和密码。拿到以后,A 就直接向授权服务器
请求令牌。
https://oauth.b.com/token? grant_type=password& username=USERNAME& password=PASSWORD& client_id=CLIENT_ID
上面 URL 中,grant_type
参数是授权方式,这里的password
表示"密码式",username
和password
是授权服务器
的用户名和密码。
授权服务器:
授权服务器
验证身份通过后,直接给出令牌。
注意,这时不需要跳转,而是把令牌放在 JSON 数据里面,作为 HTTP 回应,A 网站因此拿到令牌。
这种方式需要用户给出自己的用户名/密码,显然风险很大,因此只适用于其他授权方式都无法采用的情况,而且必须是用户高度信任的应用。
6.5 客户端模式(Client Credentials Grant)
客户端模式指客户端以自己的名义,而不是以用户的名义,向授权服务器
进行认证。
主要适用于没有前端的命令行应用。
一句话概括:客户端使用自己的标识换token,客户端使用token访问资源
。
客户端:
客户端向授权服务器
进行身份认证,并要求一个访问令牌。请求链接地址:
https://oauth.b.com/token? grant_type=client_credentials& client_id=CLIENT_ID& client_secret=CLIENT_SECRET
上面 URL 中,grant_type
参数等于client_credentials
表示采用凭证式,client_id
和client_secret
用来让授权服务器
确认 A 的身份。
授权服务器:
授权服务器
验证通过以后,直接返回令牌。
注意:这种方式给出的令牌,是针对第三方应用的,而不是针对用户的,即有可能多个用户共享同一个令牌。
6.5 授权模式选型
模式 | 需要前端 | 需要后端 | 需要用户响应 | 需要客户端密钥 |
---|---|---|---|---|
授权码模式 Authorization Code | ✅ | ✅ | ✅ | ✅ |
隐式授权模式 Implicit Grant | ✅ | ❌ | ✅ | ❌ |
密码授权模式 Password Grant | ✅ | ✅ | ✅ | ✅ |
客户端授权模式 Client Credentials | ❌ | ✅ | ❌ | ✅ |
#上述主要比較淺顯的講解了OAuth2.0 的基本邏輯,如若想詳細深入的了解,可查看官方文件OAuth或RFC 6749;亦可查看OAuth 2.0 概念及授權流程梳理做比較
#共同登入
指同時包含多種憑證校驗的登入服務,同時,也可以理解為使用第三方憑證進行校驗的登入服務。
對於兩個網站A 和B,在登入A 網站的時候用B 網站的帳號密碼,就是聯合登錄,或登入B 網站的時候使用A 網站的帳號密碼,也是聯合登入。
這樣的概念其實與上面所講的 OAuth2.0 的使用者名稱密碼式模式認證方式類似。最經典的莫過於APP 內嵌H5 的使用場景,當使用者從APP 進入內嵌的H5 時,我們希望APP 內已登入的使用者能夠存取H5 內受限的資源,而未登入的用戶則需要登入後才能訪問。
這裡想法主要有兩種,一種是原生跳轉內嵌H5 頁面時,將登入態Token 附加在URL 參數上,另一種則是內嵌H5 主動透過與原生用戶端制定的協定取得應用程式內的登入狀態。
7.2 什麼是信任登入
是指所有不需要使用者主動參與的登錄,例如建立在私有設備與使用者之間的綁定關係,憑證就是私有設備的訊息,此時不需要使用者再提供額外的憑證。信任登入又指用第三方較成熟的使用者庫來校驗憑證,並登入目前造訪的網站。
通俗點講:我們不難發現 OAtuth 2.0 其實就是信任登入的縮影,因為正是有了 OAuth,我們的信任登入才得以實現。
— 假設現在產品經理提一個需求:我想要實作使用者只能在一個裝置上登錄,禁止使用者重複登入;
— 身為優秀的程式設計師的我們當然是滿足他啦! !
8.1 什麼是唯一登錄
#唯一登錄,指的是禁止多人同時登入同一帳號,後者的登錄行為,會導致前者斷線。
通俗點講就是:A 帳號在A 電腦上登錄後,A 帳號此時又用B 電腦再次登錄,則A 電腦請求頁面時,提示「重新登入」的訊息,並跳到登入頁面
8.2 唯一登入流程圖
##8.3 唯一登入步驟詳解
##客戶端A 保存Token,並且每次請求都在header 頭中攜帶對應的Token;
用戶在客戶端B 操作:9. 掃碼登入
掃碼登入通常見於行動裝置APP 中,許多PC 端的網站都提供了掃碼登入的功能,無需在網頁上輸入任何帳號和密碼,只需要讓行動裝置APP (如微信、淘寶、QQ等等等) 中已登入使用者主動掃描二維碼
,再確認登錄,以讓PC 端的同款應用程式快速登入的方式就是掃碼登入
。
9.2 什麼是二維碼
#二維碼
又稱二維條碼,常見的二維碼為QR Code,QR 全名為Quick Response,是一個近幾年來行動裝置上超流行的一種編碼方式,它比傳統的Bar Code條碼能存更多的訊息,也能表示更多的資料類型。
透過上面所述,我們不難發現,掃碼登入需要三端(PC端
、手機端
、服務端
)來進行配合才能達到登入成功的效果;
9.3 掃碼登入的認證流程圖
9.4 掃碼登入的步驟詳解(待掃碼階段、待確認階段、已確認階段)
待掃碼階段:
PC端:
服務端:
PC 端的裝置資訊
關聯起來儲存在Redis 伺服器中,然後傳回給PC 端;同時設定一個過期時間,在過期後,使用者登入二維碼需要進行刷新重新取得。PC 端:
二維碼的形式展示,等待行動端掃描碼。且此時的 PC 端開始輪詢查詢二維碼狀態,直到登入成功。
如果行動端未掃描,那麼一段時間後二維碼會自動失效。已掃碼待確認階段:
手機端:
#開啟手機端對應
已登入
收到手機端發送的請求後,會將Token 與二維碼ID
關聯,為什麼需要關聯呢?因為,當我們在使用微信時,移動端退出時,PC 端也應該隨之退出登錄,這個關聯就起到這個作用。然後會產生一個臨時 Token,這個 Token 會回傳給行動端,一次性 Token 用作確認時的憑證。#手機端:
##服務端:
PC端:輪詢到二維碼狀態為已登入狀態,並且會取得了產生的Token,完成登錄,後續訪問都基於Token 完成。
10. 一鍵登入(適用於原生APP)
10.1 帳號密碼登入
,簡單粗暴,一般也不會出現什麼問題;
###但這種方式要求使用者要記住自己的帳號和密碼,也就是有一個記憶成本。使用者為了降低記憶成本,很可能會在不同平台使用同一套帳號密碼。從安全角度考慮,一旦某個平台的帳號密碼外洩了,就會連累到該用戶使用的其他平台。 ############另外,由於帳號和個人身分無關,這意味著同一個使用者可以註冊多個不同的帳號,也就是可能會有惡意註冊的情況發生。 ###############直到手機卡的強制實名制才得以解決! ######
10.2 手機號驗證碼登入
隨著無線互聯的發展以及手機卡實名制的推廣,手機號儼然已成為特別的身份證明,與帳號密碼相比,手機號碼可以更好地驗證使用者的身份,防止惡意註冊。
但是手機號碼註冊還是需要一系列繁瑣的操作:輸入手機號碼、等待簡訊驗證碼、輸入驗證碼、點擊登入。整個流程少說二十秒,而且如果收不到短信,也就登入補了,這類問題有可能導致潛在的用戶流失。
從安全角度考慮,也存在驗證碼洩漏的風險。如果有人知道了你的手機號,而且竊取到了驗證碼,那他也能登入你的帳號了。
所以就有了一鍵登入動作!
10.3 什麼是一鍵登入
我們想一下,為什麼我們需要驗證碼?驗證碼的作用就是確定這個手機號是你的,那除了使用短信,是否還有別的方式對手機號進行認證?
於是,就有了咱們的主角一鍵登入。
簡訊驗證碼的作用就是證明當前操作頁面的用戶與輸入手機號的用戶為相同的人,那麼實際上只要我們能夠獲取到當前手機使用的手機卡號,直接使用這個號碼進行登錄,不需要額外的操作,這就是一鍵登入。
一鍵登入能不能做,取決於運營商是否開放相關服務;隨著運營商開放了相關的服務,我們現在已經能夠接入運營商提供的 SDK 並付費使用相關的服務。
一鍵登入流程圖:
#一鍵登入步驟詳解:
#SDK 初始化:呼叫SDK 方法,傳入平台配置的AppKey 和AppSecret
喚起授權頁:呼叫SDK 喚起授權接口,SDK 會先向運營商發起獲取手機號掩碼的請求,請求成功後跳到授權頁。授權頁會顯示手機號碼遮罩以及電信商協議給使用者確認。
同意授權並登入:使用者同意相關協議,點擊授權頁面的登入按鈕,SDK 會要求本次取號的Token,請求成功後將Token傳回給客戶端
取號:將取得到的Token 傳送到自己的伺服器,由服務端攜帶Token 呼叫操作員一鍵登入的接口,呼叫成功就返回手機號碼。服務端以手機號碼登入或註冊操作,返回操作結果給客戶端,完成一鍵登入。
三大業者開放平台:
由於國內三大業者各自有獨立的SDK,所以會導致相容方面的工作會特別繁瑣。如果要採用一鍵登入的方案,不妨採用第三方提供了號碼認證服務,下列幾家供應商都擁有手機號碼認證能力:
注意:
在認證過程中,需要用戶打開蜂窩網絡,如果手機設備沒有插入SIM 卡、或者關閉蜂窩網路的情況下,是無法完成認證的。所以就算接入一鍵登錄,還是要相容傳統的登入方式,允許用戶在失敗的情況下,仍能正常完成登入流程。
在學習了解上面的 10 種鑑權方法後,我們簡單概括一下
HTTP 基本認證
適用於內部網絡,或對安全要求不是很高的網絡;Session-Cookie
適用於一般中大型的網站(行動裝置APP 除外);Token
和JWT
都適用於市面上大部分的企業型網站,JWT 效能會優於Token;單一登入
適用於子系統較多的大型企業網站;OAuth 2.0
適用於需要快速註冊使用者類型的網站;掃碼登入
適用於已完成部署了三端的企業;一鍵登入
適用於原生APP;本文轉載自:https://juejin.cn/post/7129298214959710244
作者:易師傅
#(學習影片分享:web前端)