一顿连问下来,我是焦头又烂额,欲言而又止.......
其实鉴权的方法有很多,下面我总结了常用的10种鉴权方法,那么哪一种是最适合你的系统呢?哪一种又最安全呢?
那就让我们从下文慢慢探索寻找答案吧~
白话文的意思就是:你需要用身份证证明你自己是你自己。
比如我们常见的认证技术:
在现实生活领域:门禁卡需要通过门禁卡识别器,银行卡需要通过银行卡识别器;
在互联网领域:校验session/cookie/token的合法性和有效性
权限控制(Access/PermissionControl)将可执行的操作定义为权限列表,然后判断操作是否允许/禁止
对于权限控制,可以分为两部分进行理解:一个是权限,另一个是控制。权限是抽象的逻辑概念,而控制是具体的实现方式。
在现实生活领域中:以门禁卡的权限实现为例,一个门禁卡,拥有开公司所有的门的权限;一个门禁卡,拥有管理员角色的权限,因而可以开公司所有的门。
在互联网领域:通过web后端服务,来控制接口访问,允许或拒绝访问请求。
需要说明的是,这四个环节在有些时候会同时发生。例如在下面的几个场景:
既然我们已经了解了他们之间的关系,那么我们应该好好讲讲关于前端鉴权有哪些?以及他们之间存在的差异点又在哪里呢?
在HTTP中,基本认证方案(BasicAccessAuthentication)是允许客户端(通常指的就是网页浏览器)在请求时,通过用户提供用户名和密码的方式,实现对用户身份的验证。
因为几乎所有的线上网站都不会走该认证方案,所以该方案大家了解即可
1.1认证流程图
1.2认证步骤解析
1.3优点
简单,基本所有流行的浏览器都支持
1.4缺点
1.5使用场景
内部网络,或者对安全要求不是很高的网络。
Session-Cookie认证是利用服务端的Session(会话)和浏览器(客户端)的Cookie来实现的前后端通信认证模式。
在理解这句话之前我们先简单了解下什么是Cookie以及什么是Session?
2.1什么是Cookie
众所周知,HTTP是无状态的协议(对于事务处理没有记忆能力,每次客户端和服务端会话完成时,服务端不会保存任何会话信息);
所以为了让服务器区分不同的客户端,就必须主动的去维护一个状态,这个状态用于告知服务端前后两个请求是否来自同一浏览器。而这个状态可以通过Cookie去实现。
特点:
2.2什么是Session
Session的抽象概念是会话,是无状态协议通信过程中,为了实现中断/继续操作,将用户和服务器之间的交互进行的一种抽象;
具体来说,是服务器生成的一种Session结构,可以通过多种方式保存,如内存、数据库、文件等,大型网站一般有专门的Session服务器集群来保存用户会话;
原理流程:
与Cookie的差异:
看到这里可能就有同学想到了,Session-Cookie是不是就是把Session存储在了客户端的Cookie中呢?
Bingo,的确是这样的,我们接着往下看
2.3Session-Cookie的认证流程图
2.4Session-Cookie认证步骤解析
2.5Session-Cookie的优点
2.6Session-Cookie的缺点
2.7使用场景
2.8前端常用的Session库推荐
现在我们已经得知,Session-Cookie的一些缺点,以及Session的维护给服务端造成很大困扰,我们必须找地方存放它,又要考虑分布式的问题,甚至要单独为了它启用一套Redis集群。那有没有更好的办法?
那Token就应运而生了
3.1什么是Token(令牌)
Token是一个令牌,客户端访问服务器时,验证通过后服务端会为其签发一张令牌,之后,客户端就可以携带令牌访问服务器,服务端只需要验证令牌的有效性即可。
一句话概括;访问资源接口(API)时所需要的资源凭证
一般Token的组成:
Token的认证流程图:
Token认证步骤解析:
Token的优点:
Token的缺点:
3.2什么是RefreshToken(刷新Token)
业务接口用来鉴权的Token,我们称之为AccessToken。
为了安全,我们的AccessToken有效期一般设置较短,以避免被盗用。但过短的有效期会造成AccessToken经常过期,过期后怎么办呢?
另外一种办法是:再来一个Token,一个专门生成AccessToken的Token,我们称为RefreshToken;
RefreshToken的认证流程图:
RefreshToken认证步骤解析:
3.3Token和Session-Cookie的区别
Session-Cookie和Token有很多类似的地方,但是Token更像是Session-Cookie的升级改良版。
如果你的用户数据可能需要和第三方共享,或者允许第三方调用API接口,用Token。如果永远只是自己的网站,自己的App,用什么就无所谓了。
通过第三节,我们知道了Token的使用方式以及组成,我们不难发现,服务端验证客户端发送过来的Token时,还需要查询数据库获取用户基本信息,然后验证Token是否有效;
这样每次请求验证都要查询数据库,增加了查库带来的延迟等性能消耗;
那么这时候业界常用的JWT就应运而生了!!!
4.1什么是JWT
4.2JWT的组成
JWT由三部分组成:Header头部、Payload负载和Signature签名
它是一个很长的字符串,中间用点(.)分隔成三个部分。列如:
在Header中通常包含了两部分:
除了官方字段,你还可以在这个部分定义私有字段,下面就是一个例子。
Signature部分是对前两部分的签名,防止数据篡改。
首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用Header里面指定的签名算法(默认是HMACSHA256),按照下面的公式产生签名。
客户端收到服务器返回的JWT,可以储存在Cookie里面,也可以储存在localStorage。
此后,客户端每次与服务器通信,都要带上这个JWT。你可以把它放在Cookie里面自动发送,但是这样不能跨域,所以更好的做法是放在HTTP请求的头信息Authorization字段里面。
其实JWT的认证流程与Token的认证流程差不多,只是不需要再单独去查询数据库查找用户用户;简要概括如下:
4.5JWT的优点
4.6JWT的缺点
4.7前端常用的JWT库推荐
5.1同域下的SSO(主域名相同)
当百度网站存在两个相同主域名下的贴吧子系统tieba.baidu.com和网盘子系统pan.baidu.com时,以下为他们实现SSO的步骤:
5.2跨域下的SSO(主域名不同)
到这里客户端就可以跟系统A愉快的交往啦~
(PS:脚踏两只船,感觉有点渣呀~)
6.1什么是OAuth2.0?
令牌与密码的差异:
令牌(Token)与密码(Password)的作用是一样的,都可以进入系统,但是有三点差异。
6.3隐藏式模式(ImplicitGrant)
注意:
6.4用户名密码式模式(PasswordCredentialsGrant)
如果你高度信任某个应用,OAuth2.0也允许用户把用户名和密码,直接告诉该应用。该应用就使用你的密码,申请令牌,这种方式称为"密码式"(password)。
一句话概括:用户在客户端提交账号密码换token,客户端使用token访问资源。
6.5客户端模式(ClientCredentialsGrant)
主要适用于没有前端的命令行应用。
一句话概括:客户端使用自己的标识换token,客户端使用token访问资源。
注意:这种方式给出的令牌,是针对第三方应用的,而不是针对用户的,即有可能多个用户共享同一个令牌。
7.1什么是联合登陆
这样的概念其实与上面所讲的OAuth2.0的用户名密码式模式认证方式类似。
—身为优秀的程序员的我们当然是满足他啦!!
用户在客户端A操作:
用户在客户端B操作:
9.2什么是二维码
二维码又称二维条码,常见的二维码为QRCode,QR全称QuickResponse,是一个近几年来移动设备上超流行的一种编码方式,它比传统的BarCode条形码能存更多的信息,也能表示更多的数据类型。
待扫码阶段:
已扫码待确认阶段:
已确认阶段:
缺点:
直到手机卡的强制实名制才得以解决!
随着无线互联的发展以及手机卡实名制的推广,手机号俨然已成为特别的身份证明,与账号密码相比,手机号可以更好地验证用户的身份,防止恶意注册。
我们想一下,为什么我们需要验证码?验证码的作用就是确定这个手机号是你的,那除了使用短信,是否还有别的方式对手机号进行认证?