rest - REST API 用户和客户端身份验证
问题描述
我正在构建一个 REST API 作为移动应用程序的后端。我想检查对 API 的请求是否来自我们的移动应用程序。但是,API 将要求最终用户登录才能访问某些端点。
我的问题是,我如何验证所有传入请求以确保它们来自我们自己的应用程序,同时还验证最终用户的某些请求?
我正在考虑在身份验证 HTTP 标头中发送一个包含所有请求的 API 密钥来验证移动应用程序,并且(用逗号分隔)还发送一个 JWT 以验证最终用户。虽然这可以工作,但它似乎有点“hacky”。
同时对移动应用程序和移动应用程序的最终用户进行身份验证的标准方法是什么?
解决方案
使用应用程序令牌和用户特定会话令牌是分离两者身份验证的一种方法。应用程序令牌对于您的应用程序来说是唯一的,并且应该被混淆,以便检查客户端的二进制文件不会导致容易检测到令牌。用户登录时应生成用户特定的会话令牌。客户端将此用户会话密钥添加到未来的 API 调用中,服务器将检查会话密钥是否有效,并可以使用它来查找存储的任何会话状态为客户。
但是,最好是实现完整的 oauth2 规范。如本移动 API 安全性终极指南中所述:
以下是从用户角度来看 OAuth2 令牌身份验证的工作方式(OAuth2 将此称为密码授予流程):
用户打开您的移动应用程序并提示输入他们的用户名或电子邮件和密码。
您从您的移动应用程序向您的 API 服务发送一个 POST 请求,其中包含用户的用户名或电子邮件和密码数据(通过 SSL!)。
您验证用户凭据,并为在一定时间后过期的用户创建访问令牌。
您将此访问令牌存储在移动设备上,将其视为允许您访问 API 服务的 API 密钥。
一旦访问令牌过期并且不再有效,您将重新提示用户输入他们的用户名或电子邮件和密码。
OAuth2 在保护 API 方面的优势在于它不需要您将 API 密钥存储在不安全的环境中。相反,它将生成可以临时存储在不受信任的环境中的访问令牌。
这很棒,因为即使攻击者以某种方式设法获得了您的临时访问令牌,它也会过期!这减少了潜在的损坏(我们将在下一篇文章中更深入地介绍这一点)。
推荐阅读
- python - PyQt5 - 默认日期时间为 QDateTimeEdit
- java - 使用 Jackson 序列化具有名为 value 的属性的 XML 元素
- c# - 生日计算器在时间跨度后没有价值
- sql - 使用 SQL 集合论子句时何时需要别名?
- android - requestPermissions() 不请求权限
- ios - UIPickerView 作为多个 UITextField 的 inputView
- c - 分配的不明原因丢弃 volatile 限定符
- php - gmail 禁用了我的帐户,因为我通过 PHPMailer 库发送了太多电子邮件
- mule - 如何使用不同的输入参数并行访问 API
- makefile - [CMAKE]:无法删除 cmake 使用 make clean 命令生成的 .d 和 .gcno 文件