阅读 1523

前端常见的鉴权方式

目前我们常用的鉴权有四种:

  1. HTTP Basic Authentication (HTTP基本认证)
  2. session-cookie
  3. Token 验证(包括JWT,SSO)
  4. OAuth(开放授权)

1. HTTP Basic Authentication

http1.0或1.1规范的客户端(如IE,FIREFOX)收到401返回值时,将自动弹出一个登录窗口,要求用户输入用户名和密码。 用户名及密码以BASE64加密方式加密(base64不安全!)。

客户端未未认证的时候,会弹出用户名密码输入框,这个时候请求时属于pending状态, 用户输入用户名和密码后,会带在http request header上,发送给服务器进行校验,格式如下:

 Get /index.html HTTP/1.0 
 Host:www.google.com 
 Authorization: Basic d2FuZzp3YW5n
复制代码

2. session-cookie

利用服务器端的session(会话)和浏览器端的cookie来实现前后端的认证 在服务器端创建一个会话(session),将同一个客户端的请求都维护在各自的会话中,每当请求到达服务器端的时候,先去查一下该客户端有没有在服务器端创建session,如果有则已经认证成功了,否则就没有认证。

弊端:

  1. 服务器内存消耗大: 用户每做一次应用认证,应用就会在服务端做一次记录,以方便用户下次请求时使用,通常来讲session保存在内存中,随着认证用户的增加,服务器的消耗就会很大.
  2. 易受到CSRF攻击: 基于cookie的一种跨站伪造攻击, 基于cookie来进行识别用户的话,用户本身就携带了值,cookie被截获,用户就很容易被伪造.
  3. 如果session保存在内存中,当增加为多台服务器时,会涉及到session共享的问题,因此不利于服务器的扩展。

3.Token验证

token是用户身份的验证方式,我们通常叫它:令牌。当用户第一次登录后,服务器生成一个token并将此token返回给客户端,以后客户端只需带上这个token前来请求数据即可,无需再次带上用户名和密码。

最简单的token组成:
uid(用户唯一的身份标识)、
time(当前时间的时间戳)、
sign(签名,由token的前几位+盐以哈希算法压缩成一定长的十六进制字符串,可以防止恶意第三方拼接token请求服务器)。
还可以把不变的参数也放进token,避免多次查库。
复制代码
验证流程
  1. 客户端使用用户名跟密码请求登录
  2. 服务端收到请求,去验证用户名与密码
  3. 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
  4. 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
  5. 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
  6. 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据

请求只要每次把token带上就行了,服务器端会拦截所有的请求,然后校验token的合法性,合法就放行,不合法就返回401(鉴权失败)。

它不需要在服务端去保留用户的认证信息或者会话信息,这就意味着基于token认证机制的应用不需要去考虑用户在哪一台服务器登录了,解决了session扩展性的弊端。

缺点:
  1. 占带宽: 正常情况下token要比 session_id更大,需要消耗更多流量,挤占更多带宽.(不过几乎可以忽略)
  2. 性能问题: 相比于session-cookie来说,token需要服务端花费更多的时间和性能来对token进行解密验证.其实Token相比于session-cookie来说就是一个"时间换空间"的方案.
Token与session的区别

使用Token,服务端不需要保存状态。里面本身就保存着用户的登陆状态

Token不需要借助cookie的.

时效性。session-cookie的sessionid是在登陆的时候生成的而且在登出时一直不变的,在一定程度上安全就会低,而 token是可以在一段时间内动态改变的。

可扩展性。服务端并不保存token 信息,所以token具有更好的扩展性。

Token过期与Refresh Token

如果token过期了,就要重新获取。refresh token的作用仅仅是获取新的token,因此其作用和安全性要求都较低,所以其过期时间也可以设置得长一些,可以以天为最小单位。当然如果refresh token过期了,还是需要重新登录验证的.

JWT (JSON Web Tokens)

服务器认证以后,生成一个 JSON 对象,发回给用户.之后用户与服务器通信的时候.服务器完全只靠这个对象认定用户身份。为了防止用户篡改数据,服务器在生成这个对象的时候,会加上签名。 jwt最大的特点就是: 服务器就不保存任何 session 数据了,也就是说,服务器变成无状态了,从而比较容易实现扩展。

JWT 的数据结构

它是一个很长的字符串,中间用点(.)分隔成三个部分。

分别是: Header(头部).Payload(负载).Signature(签名)

Header: 部分是一个 JSON 对象,描述 JWT 的元数据,例如:{ "alg": "HS256","typ": "JWT"}.alg属性表示签名的算法.默认是 HMAC SHA256(写成 HS256);typ属性表示这个令牌(token)的类型(type),JWT 令牌统一写为JWT。
头部的 JSON 对象使用 Base64URL 算法转成字符串。

Payload: 部分也是一个 JSON 对象,用来存放实际需要传递的数据。这个 JSON 对象也要使用 Base64URL 算法转成字符串。
注意: JWT 默认是不加密的,任何人都可以读到,所以不要把秘密信息放在这个部分。

Signature: 部分是对前两部分的签名,防止数据篡改。 首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256).
复制代码

JWT一旦签发了,就不再收服务端控制了.因为它在服务端没有记录,是无状态的,是它最大的优点也是最大的缺点.这样就会造成一种不可控性.

4. 单点登录SSO

用户只需要登录一次就可以访问所有相互信任的应用系统。

SSO一般都需要一个独立的认证中心(passport),子系统的登录均得通过passport,子系统本身将不参与登录操作,当一个系统成功登录以后,passport将会颁发一个令牌给各个子系统,子系统可以拿着令牌会获取各自的受保护资源。

为了减少频繁认证,各个子系统在被passport授权以后,会建立一个局部会话,在一定时间内可以无需再次向passport发起认证

生成一种标识,把它取名SSO-Token(或Ticket),这种标识是整个server群唯一的,并且所有server群都能验证这个token。

5. OAuth 2.0

目前最流行的授权机制,用来授权第三方应用,获取用户数据。

简单说,OAuth 就是一种授权机制。数据的所有者告诉系统,同意授权第三方应用进入系统,获取这些数据。系统从而产生一个短期的进入令牌(token),用来代替密码,供第三方应用使用。

令牌与密码

令牌(token)与密码(password)的作用是一样的,都可以进入系统,但是有三点差异。 (1)令牌是短期的,到期会自动失效,用户自己无法修改。密码一般长期有效,用户不修改,就不会发生变化。

(2)令牌可以被数据所有者撤销,会立即失效。以上例而言,屋主可以随时取消快递员的令牌。密码一般不允许被他人撤销。

(3)令牌有权限范围(scope),比如只能进小区的二号门。对于网络服务来说,只读令牌就比读写令牌更安全。密码一般是完整权限。

优点:

保证了令牌既可以让第三方应用获得权限,同时又随时可控,不会危及系统安全。

只要知道了令牌,就能进入系统。系统一般不会再次确认身份,所以令牌必须保密,泄漏令牌与泄漏密码的后果是一样的。

这也是为什么令牌的有效期,一般都设置得很短的原因。

文章分类
前端
文章标签