前端登录场景

前端登录详解

在网页上,登录几乎是每个网站都具备的功能,业界常用的方式有下面几种

  • Cookie + Session登录
  • Token 登录
  • SSO 单点登录
  • OAuth 第三方登录

基本概念

Cookie : HTTP是一种无状态的协议,客户端每次发送请求时,首先要和服务端建立一个连接,在请求完成后会断开这个连接,这样能够节省传输时的资源,但是每次请求都是独立的,无法识别请求是否来自同一个用户,Cookie出现了,由客户端保存的小型key value文件由HTTP服务器设置的,可以随着请求发送,交互信息

Session: 有了Cookie,服务端可以知道用户的传来消息,但是要对这个消息进行验证,需要通过Session,在客户端请求服务器的时候,为这次Session开辟内存空间,这样就可能进行登录验证了,Session应该存在服务端中,避免客户端Cookie中存储敏感数据,可以存在内存中,也可以存在redis中

认证:Cookie/Session认证机制就是为一次请求认证在服务端创建一个Session对象,同时在客户端创建一个Cookie对象,通过客户端传递的Cookie对象与服务器端的Session对象匹配来实现状态管理

实现流程

首次请求的时候,输入账号密码后发送HTTP请求,服务端验证后创建会话ID(SessionID),并保存在内存或者数据库中,通过set-Cookie去设置头信息,将sessionID写入Cookie中

在次请求的时候会带上上次登录时候的Cookie,会将Cookie中的SessionId保存并进行对比,如果一致就代表身份认证ok

特点

  • 维护成本高:服务器是集群的时候为了维护登录状态,需同步SessionID
  • 服务器内存占用多压力大
  • CSRF跨站伪造请求攻击:Cookie被劫持就可能会受到攻击,可以使用csrf_token(双重验证来解决)
  • 扩展性不强,没有共享登录状态
  • 手机请求不支持Cookie

Token登录

为了解决传统的Cookie和Session登录的一些痛点,出现了Token登录验证的方式

登录流程:

登录时,客户端通过用户名与密码请求登录–>服务端收到请求去验证用户名和密码–>验证通过后,服务端会签发一个带签名的token,把这个token以响应返回给客户端–>客户端收到token后,储存在浏览器本地–>客户端每次调用API的时候会发送Token–>服务端进行token鉴权

实现流程

用户在登录时,输入账号密码,服务器会验证账号密码,验证无误后会创建Token,然后将Token返回给客户端,客户端将其保存下来。

下次访问的时候带上token即可

特点

  • 无状态,可扩展:tokens是无状态的,能够被扩展,可以打给多个机器,自身是JSON
  • 安全性
  • 时效性

Token生成方式

常见的token生成方式是 JWT (Json Web Token),jwt实际上就是一个base64的字符串,有三个部分组成Header、Payload、Signature,都是json格式

  • 头部(Header):用于描述关于JWT的最基本信息,例如类型已经签名用的算法等的

    1
    {"type": "JWT","alg": "HS256" }
  • 载荷(Payload):存放一些不敏感的信息,比如用户ID之类的

  • 签名(Signature):将上面拼接完的字符串用HS256算法进行加密。在加密的时候,我们还需要提供一个密钥(secret)。加密后的内容也是一个字符串,最后这个字符串就是签名,把这个签名拼接在刚才的字符串后面就能得到完整的jwt。header部分和payload部分如果被篡改,由于篡改者不知道密钥是什么,也无法生成新的签名部分,服务端也就无法通过,在jwt中,消息体是透明的,使用签名可以保证消息不被篡改。

SSO单点登录

单点登录(Single Sign On),即SSO,目前比较流行的企业业务整合的解决方案,SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统

SSO一般需要一个独立的认证中心(passport),子系统的登录均通过passport,子系统本身将不参与登录操作,当一个系统成功登录以后,passport将会颁发一个令牌给各个子系统,子系统可以拿着令牌会获取各自的受保护资源,为了减少频繁认证,各个子系统在被passport授权以后,会建立一个局部会话,在一定时间内可以无需再次向passport发起认证。

登录流程

  • 用户首次访问时,需要在认证中心登录
  • 比如用户访问a.com下面的pageA的时候,由于没有登录,则会重定向到认证中心,并带上回调地址www.sso.com?return_uri=a.com/pageA,直接进入对应页
  • 用户输入认证信息
  • 认证中心认证有效后,重新向到a.com/PageA?ticket=exploison,带上授权码,并将认证中心sso.com的登录态写入Cookie中
  • 在 a.com 服务器中,拿着 ticket 向认证中心确认,授权码 ticket 真实有效
  • 验证成功后,服务器将登录信息写入 Cookie,返回给客户端,并保存下来
  • 继续访问a.com下的别的信息时,由于 a.com 存在已登录的 Cookie 信息,所以服务器端直接认证成功。
  • 如果认证中心登录完成之后,访问b.com下的页面
  • 由于认证中心存在之前登录过的 Cookie,所以也不用再次输入账号密码,下发 ticket 给 b.com 即可。

退出登录流程

比如在c.com的时候

  • 清空c.com中的登录态Cookie
  • 请求认证中心sso.com中的退出api
  • 认证中心遍历发过ticket的所有产品,并调用api完成退出

特点

  • 简化管理、提高用户效率、提高开发人员效率
  • CPU开销大、安全隐患、重构困难

OAuth 第三方登录

第三方登录,实质就是 OAuth 授权。用户想要登录 A 网站,A 网站让用户提供第三方网站的数据,证明自己的身份。获取第三方网站的身份数据,就需要 OAuth 授权。

为用户资源的授权提供了一个安全又简易的标准,OAuth不会涉及到第三方的账号密码信息,即可获取到用户资源的授权

流程

  • 第三方要求用户给予授权
  • 用户同意授权
  • 根据上一步获得的授权,第三方向认证服务器请求令牌(token)
  • 认证服务器对授权进行认证,确定后发放令牌
  • 第三方使用令牌向资源服务器请求资源
  • 资源服务器使用令牌向认证服务器确认令牌的正确性,确定后提供资源

具体流程(以QQ为例)

QQ登录OAuth2的处理流程主要是下面

  • 获取access_token
  • 根据access_token获取对应用户身份的openid
  • 根据access_token与openid调用OpenAPI,来请求访问或修改用户授权的资源