4种常见的鉴权方式及说明 | 8月更文挑战

2,811 阅读12分钟

这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战

一、什么是鉴权

鉴权(authentication)是指验证用户是否拥有访问系统的权利。传统的鉴权是通过密码来验证的。这种方式的前提是,每个获得密码的用户都已经被授权。在建立用户时,就为此用户分配一个密码,用户的密码可以由管理员指定,也可以由用户自行申请。这种方式的弱点十分明显:一旦密码被偷或用户遗失密码,情况就会十分麻烦,需要管理员对用户密码进行重新修改,而修改密码之前还要人工验证用户的合法身份。

为了克服这种鉴权方式的缺点,需要一个更加可靠的鉴权方式。目前的主流鉴权方式是利用认证授权来验证数字签名的正确与否。

逻辑上,授权发生在鉴权之后,而实际上,这两者常常是一个过程。

二、 鉴权分类

  • 用户鉴权,网络对用户进行鉴权,防止非法用户占用网络资源。
  • 网络鉴权,用户对网络进行鉴权,防止用户接入了非法的网络,被骗取关键信息。

这种双向的认证机制,就是AKA(Authentication and Key Agreement,鉴权和密钥协商)鉴权。

除了AKA鉴权,也可以使用其它鉴权方式。在IMS AKA鉴权广泛实施之前,或在特定的条件下(例如通过固定网络ADSL连接方式接入IMS),可以使用HTTP摘要鉴权等其他鉴权方式。

3G UMTS(Universal Mobile Telecommunication System,通用移动通讯系统)、EPS(Evolved Packet System,演进的分组系统)、IMS(IP Multimedia Subsystem,IP多媒体子系统)网络都采用了AKA双向鉴权机制,鉴权原理也大致相同。而2G网络,只有用户鉴权,无网络鉴权。

三、鉴权时机

移动网络对鉴权时机的要求为:

  • 2G、3G网络中,鉴权发生在开机、呼叫、位置更新以及在补充业务的激活、去活、登记或删除操作之前。
  • 2G网络中,运营商都是启用的“按比例鉴权”方案。
  • 3G网络中,用户首次接入网络必须鉴权,此后启用“按比例鉴权”方案。
  • IMS网络中,网络可以通过注册或重注册过程,在任何时候对用户进行鉴权。

四、鉴权方式

我们常用的鉴权有四种:

1、HTTP Basic Authentication

2、session-cookie

3、Token 验证

4、OAuth(开放授权)

4.1 HTTP Basic Authentication

这种授权方式是浏览器遵守http协议实现的基本授权方式,HTTP协议进行通信的过程中,HTTP协议定义了基本认证认证允许HTTP服务器对客户端进行用户身份证的方法。

认证过程:

1. 客户端向服务器请求数据,请求的内容可能是一个网页或者是一个ajax异步请求,此时,假设客户端尚未被验证,则客户端提供如下请求至服务器:

Get /index.html HTTP/1.0 Host:www.google.com

2. 服务器向客户端发送验证请求代码401,(WWW-Authenticate: Basic realm=”google.com”这句话是关键,如果没有客户端不会弹出用户名和密码输入界面)服务器返回的数据大抵如下:

HTTP/1.0 401 Unauthorised Server: SokEvo/1.0 WWW-Authenticate: Basic realm=”google.com” Content-Type: text/html Content-Length: xxx

3. 当符合http1.0或1.1规范的客户端(如IE,FIREFOX)收到401返回值时,将自动弹出一个登录窗口,要求用户输入用户名和密码。

4. 用户输入用户名和密码后,将用户名及密码以BASE64加密方式加密,并将密文放入前一条请求信息中,则客户端发送的第一条请求信息则变成如下内容:

Get /index.html HTTP/1.0 Host:www.google.com Authorization: Basic d2FuZzp3YW5n

注:d2FuZzp3YW5n表示加密后的用户名及密码(用户名:密码 然后通过base64加密,加密过程是浏览器默认的行为,不需要我们人为加密,我们只需要输入用户名密码即可)

5. 服务器收到上述请求信息后,将Authorization字段后的用户信息取出、解密,将解密后的用户名及密码与用户数据库进行比较验证,如用户名及密码正确,服务器则根据请求,将所请求资源发送给客户端。

效果: 客户端未未认证的时候,会弹出用户名密码输入框,这个时候请求时属于pending状态,这个时候其实服务当用户输入用户名密码的时候客户端会再次发送带Authentication头的请求。

4.2 session-cookie

HTTP Cookie(也叫Web Cookie或浏览器Cookie)是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。Cookie使基于无状态的HTTP协议记录稳定的状态信息成为了可能。

Cookie主要用于以下三个方面:

  • 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
  • 个性化设置(如用户自定义设置、主题等)
  • 浏览器行为跟踪(如跟踪分析用户行为等)

认证过程

  1. 服务器在接受客户端首次访问时在服务器端创建seesion,然后保存seesion(我们可以将seesion保存在内存中,也可以保存在redis中,推荐使用后者),然后给这个session生成一个唯一的标识字符串,然后在响应头中种下这个唯一标识字符串。

  2. 签名。这一步只是对sid进行加密处理,服务端会根据这个secret密钥进行解密。(非必需步骤)

  3. 浏览器中收到请求响应的时候会解析响应头,然后将sid保存在本地cookie中,浏览器在下次http请求de 请求头中会带上该域名下的cookie信息。

  4. 服务器在接受客户端请求时会去解析请求头cookie中的sid,然后根据这个sid去找服务器端保存的该客户端的session,然后判断该请求是否合法。

  5. 一旦用户登出,服务端和客户端同时销毁该会话在后续请求中,服务器会根据数据库验证会话id,如果验证通过,则继续处理;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NEyuKS3h-1578623143129)(/Users/mxj/百度云同步盘/学习笔记/前端全栈/网络及工具/img/image-20200110092849020.png)]

4.3 Token 验证

认证过程

  1. 用户输入登陆凭据;
  2. 服务器验证凭据是否正确,然后返回一个经过签名的token;
  3. 客户端负责存储token,可以存在localstorage,或者cookie中
  4. 对服务器的请求带上这个token;
  5. 服务器对JWT进行解码,如果token有效,则处理该请求;
  6. 一旦用户登出,客户端销毁token。

cookie与taken看上去很像,那么他们到底有什么区别呢?

cookie与taken性能对比

  1. sessionid 他只是一个唯一标识的字符串,服务端是根据这个字符串,来查询在服务器端保持的seesion,这里面才保存着用户的登陆状态。但是token本身就是一种登陆成功凭证,他是在登陆成功后根据某种规则生成的一种信息凭证,他里面本身就保存着用户的登陆状态。服务器端只需要根据定义的规则校验这个token是否合法就行。
  2. session-cookie是需要cookie配合的,居然要cookie,那么在http代理客户端的选择上就是只有浏览器了,因为只有浏览器才会去解析请求响应头里面的cookie,然后每次请求再默认带上该域名下的cookie。但是我们知道http代理客户端不只有浏览器,还有原生APP等等,这个时候cookie是不起作用的,或者浏览器端是可以禁止cookie的,但是token就不一样,他是登陆请求在登陆成功后再请求响应体中返回的信息,客户端在收到响应的时候,可以把他存在本地的cookie,storage,或者内存中,然后再下一次请求的请求头重带上这个token就行了。简单点来说cookie-session机制他限制了客户端的类型,而token验证机制丰富了客户端类型。
  3. 时效性。session-cookie的sessionid实在登陆的时候生成的而且在登出事时一直不变的,在一定程度上安全就会低,而token是可以在一段时间内动态改变的。
  4. 可扩展性。token验证本身是比较灵活的,一是token的解决方案有许多,常用的是JWT,二来我们可以基于token验证机制,专门做一个鉴权服务,用它向多个服务的请求进行统一鉴权。

4.4 OAuth(开放授权)

OAUTH协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是OAUTH的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此OAUTH是安全的。同时,任何第三方都可以使用OAUTH认证服务,任何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。

我们常见的提供OAuth认证服务的厂商有支付宝,QQ,微信。

OAuth协议又有1.0和2.0两个版本。相比较1.0版,2.0版整个授权验证流程更简单更安全,也是目前最主要的用户身份验证和授权方式。

典型案例

果一个用户拥有两项服务:一项服务是图片在线存储服务A,另一个是图片在线打印服务B。由于服务A与服务B是由两家不同的服务提供商提供的,所以用户在这两家服务提供商的网站上各自注册了用户,假设这两个用户名各不相同,密码也各不相同。

当用户要使用服务B打印存储在服务A上的图片时,用户该如何处理?

方法一:用户可能先将待打印的图片从服务A上下载下来并上传到服务B上打印,这种方式安全但处理比较繁琐,效率低下;

方法二:用户将在服务A上注册的用户名与密码提供给服务B,服务B使用用户的帐号再去服务A处下载待打印的图片,这种方式效率是提高了,但是安全性大大降低了,服务B可以使用用户的用户名与密码去服务A上查看甚至篡改用户的资源。

方法三:当服务B(打印服务)要访问用户的服务A(图片服务)时,通过OAUTH机制,服务B向服务A请求未经用户授权的RequestToken后,服务A将引导用户在服务A的网站上登录,并询问用户是否将图片服务授权给服务B。用户同意后,服务B就可以访问用户在服务A上的图片服务。整个过程服务B没有触及到用户在服务A的帐号信息。

OAuth相关术语

在认证和授权的过程中涉及的三方包括:

服务提供方(ServiceProvider),用户使用服务提供方来存储受保护的资源,如照片,视频,联系人列表。

用户(User),存放在服务提供方的受保护的资源的拥有者

客户端(Consumer),要访问服务提供方资源的第三方应用,通常是网站,如提供照片打印服务的网站也可以是桌面或移动应用程序。在认证过程之前,客户端要向服务提供者申请客户端标识。

OAuth相关的三个URL:

RequestToken URL:获取未授权的RequestToken服务地址;

UserAuthorization URL:获取用户授权的RequestToken服务地址;

AccessToken URL:用授权的RequestToken换取AccessToken的服务地址。

OAuth认证和授权过程

  1. 客户端(第三方软件)向OAUTH服务提供商请求未授权的RequestToken。即向RequestToken URL发起请求;
  2. OAUTH服务提供商同意使用者的请求,并向其颁发未经用户授权的oauth_token与对应的oauth_token_secret,并返回给使用者;
  3. 使用者向OAUTH服务提供商请求用户授权的RequestToken。即向UserAuthorization URL发起请求并在请求中携带上一步服务提供商颁发的未授权的token与其密钥;
  4. OAUTH服务提供商通过网页要求用户登录并引导用户完成授权;
  5. RequestToken授权后,使用者将向AccessToken URL发起请求,将上步授权的RequestToken换取成AccessToken。请求的参数见上图,这个比第一步多了一个参数就是RequestToken;
  6. OAUTH服务提供商同意使用者的请求,并向其颁发AccessToken与对应的密钥,并返回给使用者;
  7. 使用者以后就可以使用上步返回的AccessToken访问用户授权的资源。

简单整理就三个步骤

  1. 获取未授权的RequestToken
  2. 获取用户授权的RequestToken
  3. 用授权的RequestToken换取AccessToken