REST 是一种软件架构风格。RESTful Api 是基于 HTTP 协议的 Api,是无状态传输。它的核心是将所有的 Api 都理解为一个网络资源。将所有的客户端和服务器的状态转移(动作)封装到 HTTP 请求的 Method 之中.
而本篇文章则主要是讨论 RESTful Api 身份认证安全性设计.
没有绝对的安全,这个话题很深,下文都是自己的一些理解,水平有限,如有勘误,希望大家予以指正。
由于 RESTful Api 是基于 Http 协议的 Api,是无状态传输,所以只要和用户身份有关的请求都会带上身份认证信息。(很多时候客户端事先并不知道某个 api 后期会不会加入身份判断,所以我们一般都会选择每个请求都会带上认证信息,如果有的话。
Http Basic Authentication
Http Basic 是一种比较简单的身份认证方式。在 Http header 中添加键值对 Authorization: Basic xxx (xxx 是 username:passowrd base64 值)。
例如 username 为 zmk ,password 为 123456,请求则如下
GET /auth/basic/ HTTP/1.1
Host: xxxxx
Authorization: Basic em1rOjEyMzQ1Ng==
而 Base64 的解码是非常方便的,如果不使用 Https ,相当于是帐号密码直接暴露在请求中。
危险性高,实际开发者使用的应该几乎为 0。
顺便提下 DIGEST 认证,和 BASIC 认证相差无几,而且不适合 api 设计,实际又需要两次请求,首次请求,服务器端返回 401,并且带上 nonce 值,然后客户端再利用 username+password+nonce 默认 MD5 之后再请求。对 http 请求的作用是仅仅防止二次请求,对身份认证并没有什么提升。
Access Token
不知道是否应该这么称呼。原理即当客户端登录完毕之后,给客户端返回一个 token,服务器端控制该 token 的有效期,每次请求都带上该值,然后服务器端做验证,退出之后,客户端通知服务端端销毁 token,客户端本地也销毁。但是如果抓包获取到 token,就能任意伪造请求了。
同时 api 接口还存在被第三方开发者或者公司随意利用的风险。也就是说,别人可以非常轻易的就弄出一个你们 app 的复制版,而且还用的你们的所有资源。
危险性高,实际开发估计使用得还不少。
Api Key + Security Key + Sign
下图是我们自己每次请求的身份认证的方式,如有不足,请大家指出。可以说是 JWT 的自定义版吧。
这里的认证逻辑即:
用户登录返回一个 api_key 和 security_key;
然后客户端将 security_key 存在客户端;
当要发送请求之前,通过 function2 加密方法,把如图所示的五个值一起加密,得到一个 sign;
发送请求的时候,则将除去 security_key 之外的值,以及 sign 一起发送给服务器端;
服务器端首先验证时间戳是否有效,比如是服务器时间戳 5 分钟之前的请求视为无效;
然后根据 api_key 得到 sercurity_key;
最后验证 sign。
Api key 的作用是什么?(补)
看到有朋友在头条问了这个问题,说下我的实际使用场景:
api key 是用来标识每个不同用户的(也就是说 api key 和用户 id 一一对应的),同时也用来验证security_key 和 sign 的。
比如有 2000 万用户,以 redis 作为数据库,将 api_key 为键,security_key 作为值,api_key 散列分布(比如对末尾位字符的 ASCII 对 20 取模)到 20 个 hashes 里。
当用户请求过来的时候首先根据 api_key 找到对应的 hashes,首先 HEXISTS 检查该 api_key 是否存在,存在则通过 HGET 取出该值,最后一起验证 sign。
是否需要加上时间戳验证?
上面的认证逻辑中加密得到签名的时候,把时间戳加进去是为了在一定程度上屏蔽了一些无效的请求,可以略去,也可以设计的更加严格。如果想防止恶意的 api ddos 攻击,这一步验证肯定是不行的。需要做更多的验证,比如用户验证,ip 验证等。可以参考 github 的 api 的设计。它会在返回的 http 头信息里带上
X-RateLimit-Limit: 5000
X-RateLimit-Remaining: 4999
表示这个接口在某一时间段内,该授权用户调用该接口的最大次数为 5000次,该时间段内还剩余 4999 次。当然,这样的验证加上之后,在代码的执行效率上肯定会有所影响。
是否需要将 request_parameters 也加入到 sign 生成的算法之中?
也不是必须的,仅仅是为了请求的真实性,减少请求的伪造,比如有人抓包拿到 http 请求之后,如果没有验证 sign 这步,那么别人就可以非常简单的修改请求的参数,而请求都会生效。
这里将 request_parameters 也加入到签名之中,就减少了伪造请求的可能性,但是无法杜绝,破坏者可能就非要黑你,又对逆向工程非常熟悉,找到我们加密算法的实现,依然可以未知出合法的签名,所以我们常说,服务器端永远不能相信客户端的请求都是安全的、合法的,需要做验证的都还是不能省略。
同时这(sign算法)也造成了 api 接口调试的成本,api 测试工具必须也得实现那一套算法,或者是设置在开发环境下不做验证。我们在配置开发环境的时候则是 vpn 连测试服务器所在内网,然后进行测试,否则开发环境也存在被人利用的风险。
项目实例 https://github.com/zhoumengkang/netty-restful-server
JWT
JWT (JSON Web Token) 使用流程如下(图片来自官网)
其认证机制也是登录,发放密钥给客户端,然后客户端每次发送请求的时候通过 JWT 的算法规则组装 JWT 的Auth Header,服务器端作验证。
web 授权认证的原理万变不离其宗,都是如此。
只不过 JWT 呢,自定了一套认证协议。格式为 Header.Payload.Signature。比如 xxxxx.yyyyy.zzzzz。签名内容是有 Header+Payload+Secret 通过 HMAC SHA256 算法加密而成。
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
而请求的很多参数键值对都可以放在 Payload 里面。完整讲解请求看官方的介绍 http://jwt.io/introduction/
需要注意的一点,依照 JWT 的协议,只有一个 secret,无法得知该用户是谁,所以在 secret 该值中必须要可以解码出用户的 id。
而我们自定义认证协议的时候 header 感觉就没有必要了,使用什么算法事先定义好即可。所以我们也没选择这种方式而是上面的那种方式。
其他
oauth2.0 则属于第三方认证,不在本篇的讨论范畴之内,可以阅读 http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html
来自:周梦康
链接: http://mengkang.net/620.html
相关推荐
本文将探讨 RESTful API 设计的最佳实践,帮助开发者构建高效、易用且灵活的 API。 #### 二、RESTful API 的关键要求 设计 RESTful API 时,应遵循以下关键要求: 1. **遵循 Web 标准**:在适当的地方使用 Web ...
身份验证(Authentication)和权限验证(Permission Validation)是确保API安全的重要环节。常用的认证机制有基本认证(Basic Auth)、摘要认证(Digest Auth)和OAuth。基本认证是通过用户名和密码进行认证,摘要...
本文旨在深入探讨RESTful API的核心设计理念及其应用实践。 #### 一、协议 RESTful API与用户之间的通信协议统一使用HTTP(s)。HTTP协议是一种无状态的、基于请求与响应模型的应用层协议,它能够很好地支持不同类型...
本文将探讨C#中RESTful API设计的最佳实践,包括URL设计、状态码使用、版本控制、安全性考虑以及错误处理等方面。 设计和实现RESTful API是一个需要细致考虑的过程。遵循最佳实践,如使用合适的HTTP方法、状态码、...
在这个项目中,我们将探讨Gin框架的核心特性,RESTful API设计原则,以及SQLite在Go中的应用。 Gin是一个轻量级的HTTP服务器框架,它的核心是基于Gorilla Mux,提供了一个高效的路由系统,允许开发者通过路径、方法...
5. **认证与安全**:如果API需要身份验证,应详细解释认证机制,如OAuth2、JWT等。 6. **版本管理**:说明如何处理API版本变化,以便开发者能够适应未来的更新。 为了实现这样的自定义风格,我们可以利用`...
本文将探讨使用Golang开发RESTful API的最佳实践,包括设计原则、编码实践、安全性、性能优化等方面。 使用Golang开发RESTful API时,遵循最佳实践可以提高代码的可维护性、安全性和性能。从设计API开始,到编码、...
在本案例中,我们将探讨如何利用Spring Security集成JWT来实现RESTful API的认证与授权。首先,我们需要了解RESTful API的基本原则,即通过HTTP方法(如GET、POST、PUT、DELETE等)和资源URL来操作数据。 1. **JPA...
4. 安全性设计:包括如何使用HTTPS来保证数据传输安全,以及如何在API中实现身份验证和授权。 5. API版本管理:随着业务需求的变化,API的版本管理是不可避免的。书中可能会探讨如何在不影响现有用户的情况下,平滑...
标题 "Go-从任何PostgreSQL数据库提供RESTfulAPI" 暗示了我们将探讨如何使用Go编程语言构建一个服务,该服务能够通过RESTful接口暴露PostgreSQL数据库中的数据。Go是一种高效、轻量级的开源语言,常用于构建网络服务...
在本文中,我们将深入探讨一个与WAF(Web Application Firewall)虚拟化版本相关的Restful API接口,主要涵盖用户管理和业务口IP配置。 ### 1. 接口约定 在WAF的Restful API设计中,接口通常遵循以下约定: - **...
7. **安全考虑**:RESTful API应考虑安全性,例如使用HTTPS进行加密传输,认证(如OAuth2.0或JWT)和授权机制,以及防止攻击如CSRF(跨站请求伪造)和XSS(跨站脚本)。 8. **错误处理**:良好的API设计会提供结构...
7. **安全性考虑**:在生产环境中,我们需要考虑API的安全性,可能需要实现身份验证和授权。Spring Security可以与Spring CXF很好地集成,提供基于角色的访问控制和OAuth2支持。 8. **监控和日志**:为了监控服务...
8. **安全性考虑**:在实际应用中,还需考虑API的安全性,如认证授权、防止跨站请求伪造(CSRF)和跨站脚本攻击(XSS),可以使用Flask-JWT或Flask-HTTPAuth等扩展实现。 这个项目不仅涵盖了Flask和RESTful API的...
- **自动数据验证**:基于注解的方式,可以方便地对请求参数进行验证,提高数据安全性。 - **ORM支持**:内置了强大的ORM(对象关系映射)系统,支持MySQL、SQLite等多种数据库,使数据库操作更加简单。 - **...
- 如何处理RESTful API中的身份验证和授权问题。 - API版本管理的最佳实践。 - 性能优化和安全措施。 RESTful API设计的标准通常与HTTP协议紧密相关,了解HTTP协议的基础知识对于设计和实现高质量的RESTful API至关...
- **身份验证**:确保API的安全性,防止未授权的访问。 - **性能优化**:针对高并发场景下的性能优化措施,如缓存策略等。 #### 其他Python Web框架 除了Django和Flask之外,还有一些其他的Python Web框架也值得...
6. **安全考虑**:在生产环境中,我们还需要考虑API的安全性,比如使用OAuth2进行身份验证和授权,使用HTTPS确保通信安全,以及防止SQL注入和跨站脚本攻击。 7. **性能优化**:内存模型的效率取决于数据结构和算法...
在IT行业中,调用云服务API是常见的操作,特别是在开发基于云计算的应用时。...记得在实际开发中,始终遵循最佳实践,确保代码的健壮性和安全性。同时,保持对京东云API更新的关注,以便及时利用新的功能和服务。