您当前的位置:首页 > 计算机 > 精彩资源

Web API接口鉴权方式

时间:08-28来源:作者:点击数:

一、什么是鉴权?为什么要鉴权

鉴权(authentication),也叫做认证,即验证用户是否拥有访问系统的权利。

HTTP本身是无状态的请求,每次请求都是一次性的,并不会知道请求前后发生了什么。但在很多情况情况下都需要维护状态,最典型的就是用户登录系统,并在系统中进行一系列操作

API接口直接暴露在互联网上是存在安全风险的,如果不进行鉴权,就有可能被网上的不法分子恶意攻击(如:爬虫,恶意访问等),使得api资源被非法访问占用,正常用户访问受阻。因此鉴权十分必要,只有鉴权成功的请求才能请求服务,否则就被拦截

请添加图片描述

二、Cookie/Session鉴权

为每个用户颁发一个身份牌

为了识别用户,可以为每个用户设置一个“身份牌”,“身份牌”里面可以存放用户的信息,每次请求的时候都带上这个“身份牌”,这样就可以用来识别用户了。而这个“身份牌”就是我们经常提到的“cookie”

请添加图片描述

Session会话的引入

随着web应用的告诉发展,越来越多的用户信息需要存储,如果仅仅依靠Cookie字段存储,会大大增加每次请问的负担。

因此引入会话(session)的概念,使用一个会话ID(sessionID)映射到用户的各种信息上,每次请求只需要在cookie携带上sessionID就可以解决cookie增长的问题

请添加图片描述

为了更好的负载均衡与容灾,后端服务器一般使用分布式方式部署,一个用户的Session信息在单台服务器上创建后需要同步给其余的服务器。因此Session映射采用Redis等缓存服务器方式才能解决跨地域多机房问题

(为了负载均衡与容灾,Redis集群也需要使用多机房部署)

请添加图片描述

局限

  • 依赖cookie,cookie可以被禁用,也可以被劫持篡改
  • 移动端中cookie和session机制不被支持,跨平台不好兼容
  • 缓存服务器的多机房信息同步需要时间,如果服务某个机房出现问题,依然可能造成用户Session短暂失败

二、token授权之JWT

分散压力

既然基于cookie的session鉴权存在上述问题,那么能否改变一下思路,跳出以上的局限性。

Session会话机制的痛点在于,Session的用户解析需要后端服务来维护逻辑,甚至还需要一个缓存服务器来维护,这使得一次请求的链路变长,出现问题的概率也比较大

那干脆让客户端来维护自己的用户信息就好了,这样大量的用户信息就分散到各个用户的设备上,服务器的压力就会减少很多

客户维护鉴权信息的机制类似于http协议也是无状态的,这也使得整个服务拓展性大大提升

用token代替session

  • 用户第一次登录,服务器验证用户,通过后生成一个token
  • 在第一次返回时将token返回给客户端,客户端存储下来,下次请求时携带上该token
  • 之后只要验证token是否有效即可
  • 为了避免篡改,可以在token中使用加密算法生成签名,加入token(私钥保存在服务器上,因此签名无法被破解)
    请添加图片描述
JWT(JSON Web Token)token生成标准

JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。因为携带了数字签名,因此该信息可以被验证和信任的

JWT由三部分数据组成,三部分由 点(.) 进行分割

  • Header(头部)
  • Payload(负载)
  • Signature(签名)
    Header.Payload.Signature
Header

Header 部分是一个 JSON 对象,描述 JWT 的元数据,例如:

{
  "alg": "HS256",
  "typ": "JWT"
}

alg属性表示签名的算法(algorithm),默认是 HMAC SHA256(写成 HS256);typ属性表示这个令牌(token)的类型(type),JWT 令牌统一写为JWT

最后,将上面的 JSON 对象使用 Base64URL 算法转成字符串

Payload

Payload 部分也是一个 JSON 对象,用来存放实际需要传递的数据。JWT 规定了7个官方字段,可以从中选择使用

iss (issuer):签发人
exp (expiration time):过期时间
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间
iat (Issued At):签发时间
jti (JWT ID):编号

当然也可以自定义字段,不过由于这部分数据是明文传送,所以不要在payload字段上存放任何私密信息

Signature

Signature 部分是对前两部分的签名,防止数据篡改。

首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名。

HMACSHA256(base64UrlEncode(header)+"."+base64UrlEncode(payload),secret)

算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.)分隔,就可以返回给用户

因为使用了签名,因此即使泄露,也无法被篡改

局限
  • 服务器不保存Session信息,在没有特殊逻辑的情况下,无法在使用过程中废止某个 token,也不能更改 token 的权限,一旦 JWT 签发了,在到期之前就会始终有效
  • Token本身就是认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT 的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证
  • 为了减少盗用,JWT 不应该使用 HTTP 协议明码传输,要使用 HTTPS 协议传输

三、token授权之OAuth2.0

严格来讲,OAuth2.0不算一种授权方式,而是一个安全的授权认证的框架。为系统中不同角色、用户、服务前端应用(比如API),以及客户端(比如网站或移动App)提供了一套相互认证的框架

所以一般而言,在OAuth2.0中存在三种角色:服务提供方,用户,第三方服务 ;用户授权第三方服务使用自身的某些权限,去访问服务提供方的资源(比如用qq账户登录微博)

OAuth2.0分为两步,获取Authorization以及获取Token

获取Authorization

  • 用户在授权界面,选择需要授权的权限点,登录确定授权
  • 授权后回调第三方服务的回调地址
  • 通过回调地址,发送Authorization(可以看做是验证码,有效期不长)给第三方服务

获取Token并维护Token有效性

  • 通过上面拿到的Authorization调用服务提供方的接口获取token
  • token由access token与refresh token两个token组成,access token有效性比refresh token短
  • 访问服务提供方接口需要使用access token,而当access token快过期的时候就需要用refresh token请求token刷新接口,获取新的token
    请添加图片描述
    OAuth 2.0 rfc文档:https://www.rfc-editor.org/rfc/rfc6749

OAuth2.0提供了4种认证方式,上面是最为复杂的一种,授权码模式,其余3种授权方式如下

简化模式

不通过第三方应用程序的服务器,直接在浏览器中向认证服务器申请令牌,跳过了"授权码"这个步骤。所有步骤在浏览器中完成,令牌对访问者是可见的,且客户端不需要认证

请添加图片描述

(A)客户端将用户导向认证服务器。

(B)用户决定是否给于客户端授权。

(C)假设用户给予授权,认证服务器将用户导向客户端指定的"重定向URI",并在URI的Hash部分包含了访问令牌。

(D)浏览器向资源服务器发出请求,其中不包括上一步收到的Hash值。

(E)资源服务器返回一个网页,其中包含的代码可以获取Hash值中的令牌。

(F)浏览器执行上一步获得的脚本,提取出令牌。

(G)浏览器将令牌发给客户端。

密码模式

用户向客户端提供自己的用户名和密码。客户端使用这些信息,向"服务商提供商"索要授权。

在这种模式中,用户必须把自己的密码给客户端,但是客户端不得储存密码。这通常用在用户对客户端高度信任的情况下,比如客户端是操作系统的一部分,或者由一个著名公司出品。而认证服务器只有在其他授权模式无法执行的情况下,才能考虑使用这种模式

请添加图片描述

(A)用户向客户端提供用户名和密码。

(B)客户端将用户名和密码发给认证服务器,向后者请求令牌。

(C)认证服务器确认无误后,向客户端提供访问令牌。

客户端模式

指客户端以自己的名义,而不是以用户的名义,向"服务提供商"进行认证

请添加图片描述

(A)客户端向认证服务器进行身份认证,并要求一个访问令牌。

(B)认证服务器确认无误后,向客户端提供访问令牌。

优点

  • 更安全,客户端不接触用户密码
  • 资源服务器可以和授权服务器解耦
  • 适用多种客户端架构场景

缺点

  • 协议框架太宽泛,每个服务又都自己的实现,兼容性和互操作性比较差
  • 客户端需要维护token有效性,维护定时刷新token任务

四、ak/sk认证鉴权

  • 服务提供方需要给每个用户分配一对 Access Key Id(AK) / Secret Access Key(SK)
  • 双方约定同样的加密算法,利用 时间戳,sk,nonce(一个随机值,为了避免请求重放),参数等信息作为计算因子,算出sign签名
  • 用户在调用api时,需要提供自己的身份认证(AK),时间戳、nonce以及加密好的sign签名
  • 服务提供方验证签名是否过期,验证nonce是否唯一,并利用同样的算法算出sign,与传入sign进行比对,如果一致则通过认证
    请添加图片描述

优点

  • 安全性高,在秘钥与算法不泄露情况下,签名无法破解
  • 有过期时间,可以避免签名长期有效的情况
  • 有防止重放机制,即使签名被捕获,也无法再次利用相同的签名进行请求

缺点

  • 对于服务调用方与被调用方都需要一定的编码要求
  • 每次请求都需要重新计算签名,不那么轻量
  • 服务提供方需要维护ak/sk关系,并且需要维护nonce是否唯一逻辑
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门