参考:
如何在PHP中实现RESTful API的身份验证-php教程-PHP中文网
什么是 RESTful API 身份验证方法 - PingCode
【精选】RESTFUL API API身份认证_c# restful api预验证_终生成长者的博客-优快云博客
浅谈 REST API 身份验证的四种方法-腾讯云开发者社区-腾讯云
如何使用 RESTful API 实现用户认证和授权?-JavaScript中文网-JavaScript教程资源分享门户
--------------------------------------------------------------------------------------------------------------------------
RESTful API是一种常用的互联网应用程序接口设计风格。在实际开发中,为了保护API的安全性,我们通常需要对用户进行身份验证,不然所有人都能请求你的接口,会带来严重的后果。
RESTful 服务客户端必须向服务器证明其身份才能确立信任。RESTful Web 服务必须首先对请求进行身份验证,然后才能发送响应。
一、HTTP 身份验证
HTTP身份认证方案一共有10种,目前最常用的就是前两种:
- 基本认证
- 令牌认证
1.1 基本认证(Basic Authentication)
基本认证是最简单的一种身份验证方式。
基本认证的原理是通过在HTTP请求头部添加一个Authorization字段来传递用户凭证。例如,客户端在请求头中发送用户名和密码,其使用 base64 编码进行安全传输。
例如:
Authorization: Basic fasgfkaskjg8798f=
我们可以通过获取HTTP请求头部信息来实现基本认证。
安全等级:差
1.2令牌认证(Bearer authentication)
令牌认证(常用),也称为承载认证,就是准确的说应该是“Bearer authentication”,Bearer意思就是承载的意思,那么令牌认证可以理解为 承载有权访问某资源的令牌。
这个令牌你就当做是古代的城池令牌,比如你是一个战士,你想调用兵力,必须持有某某令牌,每个令牌的权利范围不一样,令牌由朝廷统一发放。
在这里我们可以看出令牌认证有以下特点:
- 令牌的权限可控(不同令牌权限不一样)
- 令牌由服务端生成(朝廷)
它通常是由服务器响应某个登录请求而生成的。
在向受保护的资源发出请求时,客户端必须在认证的header中发送该令牌。
令牌认证举例:
Authorization: Bearer WmLkiNzaZuR5aas4m+FE429wWpo=
承载认证方案最初是作为RFC-6750中OAuth 2.0的一部分被创建的。不过,有时它也会被单独地使用到。
与基本身份验证类似,承载身份验证需要通过HTTPS(即SSL)来实现。
二、Token认证(Token Authentication)
token是“令牌”的意思,里面包含了用于认证的信息。Token认证是一种常见的身份验证方式。
1. 在第一次登录认证后为用户生成一个 唯一的 有一定有效期的 Token。
2. 服务器会将这个 token 用文件、数据库或缓存服务器等方法存下来,用于之后请求中的比对,并将该Token返回给客户端。
3. 客户端将其存储于浏览器的 Cookie 或 LocalStorage 之中,之后客户端的每次请求都需要在HTTP头部中添加一个Authorization字段,用于传递Token信息。
2.1 JWT
我们可以使用JSON Web Token(JWT)来实现Token认证。
2.1.1 JWT组成
在JWT中,Token有三部分组成(header、payload有效载荷、signature签名),中间用.隔开,并使用Base64编码。
下面是JWT中一个Token的示例:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE1MjgwMTY5MjIsImlkIjowLCJuYmYiOjE1MjgwMTY5MjIsInVzZXJuYW1lIjoiYWRtaW4ifQ.LjxrK9DuAwAzUD8-9v43NzWBN7HXsSLfebw92DKd1JQ
(1) header
JWT Token 的 header 中,包含两部分信息:
1. Token 的类
2. Token 所使用的加密算法
例如:
{
“typ”: “JWT”,
“alg”: “HS256”
}
该例子说明Token类型是JWT,加密算法是HS256。
(2) payload有效载荷
Payload中携带Token的具体内容,里面有一些标准的字段,当然你也可以添加额外的字段,来表达更丰富的信息,比如记录请求用户名。
标准字段有:
iss:JWT Token 的签发者
sub:主题
exp:JWT Token 过期时间
aud:接收 JWT Token 的一方
iat:JWT Token 签发时间
nbf:JWT Token 生效时间
jti:JWT Token ID
例如:
{
“id”: 2,
“username”: “kong”,
“nbf”: 1527931805,
“iat”: 1527931805
}
(3) signature签名
Signature通过如下方式生成:
1.用Base64对header.payload进行编码
2.用Secret对编码后内容进行加密,加密后内容即为Signature
Secret 相当于一个密码,存储在服务端,一般通过配置文件来配置 Secret 的值。
签名后服务端会返回生成的 Token,客户端下次请求会携带该 Token,服务端收到 Token 后会解析出 header.payload,然后用相同的加密算法和密码对 header.payload 再进行一次加密,并对比加密后的 Token 和收到的 Token 是否相同,如果相同则验证通过,不相同则返回 HTTP 401 Unauthorized 的错误。
三、OAuth 2.0 授权机制
OAuth,英文全称:Open Authentication
,开放式身份验证。
OAuth2.0(常用)是一种常用的开放标准,用于授权第三方应用访问受保护资源。
OAuth的工作原理:
如图:
- 客户端向资源服务器请求授权,这个时候通常就是以用户名和密码进行登录
- 授权通过后,资源服务器同意客户端授权许可
- 客户端拿着资源服务器授权许可去认证服务器申请令牌
- 认证服务器验证授权通过后给客户端生成令牌
- 客户端仅拿着令牌请求资源服务器
- 资源服务器验证令牌的有效时间
- 验证令牌无误且有效后,向客户端返回其请求的资源
令牌通常具有有限的范围和有效期。其中,常见的OAuth实现方式会用到如下一到两种令牌:
- 访问令牌:就像发送API密钥一样,它允许应用程序访问用户的数据。当然,我们也可以设置访问令牌的到期时间。
- 刷新令牌:作为OAuth流的一部分,刷新令牌会在过期时,去检索新的访问令牌。由于OAuth2结合了身份验证与授权,因此它允许更为复杂的、范围与有效性的控制。
OAuth 2.0认证实现起来比较快速、容易,而且扩展性比较强。
安全等级:较高
OAuth 结合密码和令牌实现对任何系统的高度安全登录访问。服务器首先请求密码,然后再额外请求令牌以完成授权流程。其可以随时查看令牌,也可以在特定范围和长度的一段时间内查看令牌。
四、API 密钥认证
API密钥认证工作流程:
- 客户端先去向授权服务器请求到唯一的API KEY(由数字和字母组成,一般至少 30 个字符长)
- 生成后的KEY可以录入数据库记录
- 客户端访问API服务的带上API KEY进行验证
API KEY 举例:
Authorization: Apikey fa34sfs32wrwr3432wfa3532tfsaf3f
API 密钥认证使用率非常高,而且也非常灵活。
API KEY使用的时候完全取决于开发者,可以存放在header、body甚至查询参数中。
API 密钥的安全性较低,因为客户端必须传输密钥,其易受网络盗窃的攻击。
由于API密钥非常简单,因此我们可以将其作为单个标识符,运用到某些用例中。例如,我们可以通过限制某个API只具备“读取”权限,而禁止它调用编辑、修改或删除等安全相关的命令。
不过,由于任何请求服务的人都需要发送其密钥,而从理论上说,该密钥在网络传输的过程中可能会被任何不安全的节点所接收到,因此这势必存在着密钥被暴露、甚至是被替换的风险。可见,在设计REST API的相关认证机制时,需要通过安全测试,来检查各种常见的漏洞。
安全等级:一般
五、OpenID Connect
OpenID Connect,英文缩写:OIDC,是一个 OpenID 基金会 (OIDF) 标准,它是基于 OAuth 2.0 框架之上的身份验证协议,允许在用户尝试访问受保护的 HTTPs 端点时验证用户身份。
OpenID Connect 支持所有类型的客户端,包括基于 Web 的客户端、移动客户端以及JavaScript客户端在内的一系列客户端。
为啥会出现OpenID Connect?
最大的原因就是OAuth 2.0 本质上是一种授权协议。
试想一下这样的场景:有多个资源服务器,你从一个资源服务器上得到授权并且拿到token,你就可以用这个token去访问跟此资源服务器授权类型的网站,这种就是极其不安全的,这就是跨站点访问密码。
因为OAuth 2.0是跟用户信息绑定的,认证服务器在验证完授权服务器的信息无误后就会生成一个跟用户信息相关的token。
举个最简单的生活例子,比如有个军事重地,需要刷卡才能进,那么想要进去,肯定想到先去办张有进入权限的卡,这个卡是跟某某将军的身份证绑定,你通过某种手段拿到了将军的身份证,办理人员只认身份证,身份证无误,给你办了这张卡,你大摇大摆的拿着这张卡进入到军事基地开始谋划大事。
这个就是OAuth 2.0最大的问题:为啥在刷卡进入的时候不验证一下,你到底是不是那个将军?
所以OpenID Connect出现了!
OpenID Connect通过定义一套登录流程,使得客户端应用程序能够对用户进行身份验证,并获取有关该用户的信息(或“声明”),包括:用户名、电子邮件等。同时,用户身份信息会在安全的JSON Web Token(JWT)中予以编码,被称为ID令牌。
安全等级:高