安全的RESTful API,可供Web App(角度),iOS和Android使用

Hou*_*man 33 iphone android restful-authentication oauth flask

我必须制定一个计划来开发一个RESTful API(Python/Flask),可以被我们未来的Web应用程序(Angularjs)和移动应用程序(iOS/Android)使用.

我已经研究了三天,并且遇到了几种情况:使用HTTPS是下面方法的一种方法,以保证它更安全.但https速度较慢,这可能意味着我们需要更快,更昂贵的服务器.

  1. 对于API的每个请求,使用Basic-Http-Auth并通过线路以普通(但https)发送用户名/密码.
  2. 使用Digest-Auth,它是密码的哈希值,跟踪将是自动的.这适用于Web应用程序,但是我无法确认iPhone和Android是否会本机支持.如果他们这样做,这可能是一个简单的解决方案!
  3. 使用自定义http标头,我会在成功验证后在http标头中发送自定义Auth字符串.但是我必须确保我为用户发出的每个请求发送此身份验证代码.这使得它与1)完全相同,不同之处在于未使用普通密码,并且授权代码可以在没有任何风险的情况下过期.同样有问题的是跟踪授权代码,该代码不再像2)中那样自动化
  4. 使用OAuth是一种选择.但它很难建立起来.如果没有更好的方法,也许这是唯一的方法?
  5. 如本篇文章所述,像Amazon S3一样保护API .简而言之,他说服务器和客户端都知道私钥,他们会用它来散列通信.这就像强盗握手,如果他知道帮派握手,你只会信任送货员.有人问道:

如何在纯HTML5应用程序中保持私钥"安全"?

你完全正确; 在纯HTML5(JS/CSS/HTML)应用程序中,没有保护密钥.您可以通过HTTPS进行所有通信,在这种情况下您不需要密钥,因为您可以使用标准API_KEY或其他友好标识符安全地识别客户端,而无需HMAC的需要或复杂性.

换句话说,首先在Web应用程序中使用该方法甚至没有意义.老实说,我不明白这应该如何在移动设备上运行.用户下载我们的应用程序,如何将私钥从iphone发送到服务器?我转移它的那一刻,它将受到损害.

我越是研究我越是优柔寡断.

我希望能问一些以前做过这个并且可以分享经验的专业人士.非常感谢

And*_*nez 67

您似乎将两个不同的概念混淆在一起.我们开始谈论加密流量(HTTPS),然后我们开始讨论管理经过身份验证的会话的不同方法.在安全的应用程序中,这些不是相互排斥的任务.似乎也可能存在误解会话管理如何影响身份验证的误解.在此基础上,我将提供有关Web应用程序/ web api会话管理,身份验证和加密的入门知识.

介绍

会话管理

默认情况下,HTTP事务是无状态的.HTTP没有指定任何方法让您的应用程序知道已从特定用户发送HTTP请求(已验证或未验证).

对于强大的Web应用程序,这是不可接受的.我们需要一种方法来关联跨多个请求的请求和数据.为此,在对服务器的初始请求时,需要为用户分配"会话".通常,会话具有发送给客户端的某种唯一ID.客户端使用每个请求发送该会话ID,并且服务器使用在每个请求中发送的会话ID来正确地为用户准备响应.

重要的是要记住'会话ID'可以被称为许多其他东西.其中的一些示例是:会话令牌,令牌等.为了保持一致性,我将对此响应的其余部分使用"会话ID".

来自客户端的每个HTTP请求都需要包含会话ID; 这可以通过多种方式完成.热门的例子是:

  1. 它可以存储在cookie中 - 当前域的cookie会在每次请求时自动发送.
  2. 它可以在URL上发送 - 每个请求都可以在URL上发送会话ID,不会建议,因为会话ID将保留在客户端历史记录中
  3. 它可以作为HTTP标头发送 - 每个请求都需要指定标头

大多数Web应用程序框架都使用cookie.但是,依赖于JavaScript和单页设计的应用程序可能会选择使用HTTP标头/将其存储在服务器可观察的其他位置.

记住通知客户端其会话ID和包含会话ID的客户端请求的HTTP响应是完全纯文本并且100%不安全是非常重要的.为了解决这个问题,需要对所有HTTP流量进行加密; 这就是HTTPS的用武之地.

同样重要的是要指出我们还没有谈到将会话链接到我们系统中的特定用户.会话管理只是将数据与访问我们系统的特定客户端相关联.客户端可以处于已验证状态和未验证状态,但在这两种状态下,它们通常都有会话.

认证

身份验证是我们将会话链接到系统中特定用户的位置.这通常由登录过程处理,其中用户提供凭证,验证这些凭证,然后我们将会话链接到我们系统中的特定用户记录.

用户又通过访问控制列表和访问控制条目(ACL和ACE)与细粒度访问控制的权限相关联.这通常被称为"授权".大多数系统始终具有身份验证和授权.在一些简单的系统中,所有经过身份验证的用户都是相同的,在这种情况下,您将无需通过简单身份验 有关此问题的进一步信息超出了此问题的范围,但请考虑阅读有关ACE/ACL的内容.

可以将特定会话标记为以不同方式表示经过身份验证的用户.

  1. 他们存储在服务器端的会话数据可以存储他们的用户id /一些其他标志,表示该用户被认证为特定用户
  2. 另一个用户令牌可以像会话ID一样发送到客户端(通过未加密的HTTP与发送未加密的会话ID一样不安全)

两种选择都没问题.它通常归结为您正在使用的技术以及它们默认提供的功能.

客户端通常会启动身份验证过程.这可以通过将凭据发送到特定URL(例如yoursite.com/api/login)来完成.但是,如果我们想要"RESTful",我们通常会通过某个名词引用资源并执行"创建"操作.这可以通过要求将凭证POST发送到yoursite.com/api/authenticatedSession/来完成.其中的想法是创建一个经过身份验证的会话.大多数网站只是将凭证发布到/ api/login等.这是"真"或"纯"基于REST的理想出发,但大部分人觉得这是一个简单的概念,而不是想到它是"创造一个验证会话".

加密

HTTPS用于加密客户端和服务器之间的HTTP流量.在依赖经过身份验证和未经身份验证的用户的系统上,依赖于经过身份验证的用户的所有流量都需要通过HTTPS进行加密; 没有办法解决这个问题.

这样做的原因是,如果您对用户进行身份验证,与他们共享一个秘密(他们的会话ID等),然后开始以纯HTTP方式对该秘密进行游行,他们的会话可能被中间人攻击劫持.黑客将等待流量通过观察到的网络并窃取秘密(因为它通过HTTP发送纯文本),然后启动与服务器的连接假冒原始客户端.

人们解决这个问题的一种方法是将请求远程IP地址与经过身份验证的会话相关联.这是无效的,因为任何黑客都能够在他们的虚假请求中欺骗他们的请求远程IP地址,然后观察你的服务器发回的响应.除非您跟踪历史数据并使用它来识别特定用户的登录模式(如谷歌那样),否则大多数人会认为这甚至不值得实施.

如果您需要在HTTP和HTTPS部分分割你的网站,这是至关重要的是,HTTP流量不发送或接收会话ID或用于管理用户的认证状态的任何标记.在非HTTP请求/响应中不发送敏感应用程序数据也很重要.

保护Web应用程序/ API中数据的唯一方法是加密流量.

你的话题一个接一个

基本-HTTP-AUTH

  • 身份验证:是的
  • 会话管理:没有
  • 加密:没有

这是一种仅通过Web资源进行身份验证的方法.基本身份验证通过URL标识的资源进行身份验证.这是Apache HTTP Web Server最常用的,使用基于.htaccess的目录/位置身份验证.必须随每个请求发送凭据; 客户通常会为用户透明地处理此问题.

基本身份验证可以被其他系统用作身份验证模式.但是,使用Basic-Http-Auth的系统提供身份验证和会话管理,而不是Basic-Http-Auth本身.

  • 这不是会话管理.
  • 这不是加密; 内容和凭据几乎是100%纯文本
  • 这不保护应用程序的HTTP请求/响应的内容.

文摘 - 验证

  • 身份验证:是的
  • 会话管理:没有
  • 加密:没有

这与Basic-Http-Auth完全相同,增加了一些简单的MD5消化.不应依赖此摘要而不是使用加密.

  • 这不是会话管理.
  • 这不是加密; 摘要很容易被打破
  • 这不保护应用程序的HTTP请求/响应的内容.

OAuth的

  • 身份验证:是的
  • 会话管理:没有
  • 加密:没有

OAuth只允许您拥有外部服务验证凭据.之后,由您来管理/处理OAuth提供商的身份验证请求结果.

  • 这不是会话管理.
  • 这不是加密; 您的网站流量仍然是纯文本.由于HTTPS限制,身份验证过程将是安全的,但您的应用程序仍然容易受到攻击.
  • 这不保护应用程序的HTTP请求/响应的内容.

黑帮握手/自定义HTTP标头

  • 身份验证:是的,可能
  • 会话管理:是的,可能
  • 加密:没有

"自定义HTTP标头"是一种"黑帮握手"; 因此,我将使用相同的部分来讨论它们.唯一的区别是"自定义HTTP标头"指定将存储hanshake(会话ID,令牌,用户身份验证toke等)的位置(即在HTTP标头中).

重要的是要注意,这些不指定如何处理身份验证,也不指定如何处理会话管理.它们实质上描述了会话ID /身份验证令牌的存储方式和位置.

身份验证需要由您的应用程序或第三方(例如OAuth)处理.会话管理仍然需要实施.有趣的是,如果您愿意,可以选择合并两者.

  • 这不是加密; 您的网站流量仍然是纯文本.如果您使用OAuth,则由于HTTPS限制,身份验证过程将是安全的,但您的应用程序仍然容易受到攻击.
  • 这不保护应用程序的HTTP请求/响应的内容.

你需要做什么

...我强烈建议您确保您了解安全的强大Web应用程序需要以下内容:

  1. 加密(HTTPS几乎是您唯一的选择)
  2. 会话管理
  3. 身份验证/授权

授权依赖于身份验证.身份验证依赖于会话管理和加密,确保会话未被劫持且凭据未被截获.

烧瓶登录

我认为你应该考虑使用flask-login作为避免重新实现轮子的方法.我个人从未使用它(我在python中使用pyramid用于web应用程序).但是,我之前在Web应用程序/ python板中看到过它.它处理身份验证和会话管理.通过HTTPS抛出您的web api /应用程序,您将拥有这三个(加密,会话管理和用户身份验证).

如果你不能/不能使用flask-login,请准备自己编写,但首先要研究如何创建安全的身份验证机制.

如果可能的话,如果您不了解如何编写身份验证过程,请不要在没有首先了解黑客如何使用基于模式的攻击,计时攻击等的情况下尝试.

请加密您的流量

...超越了你可以避免使用HTTPS并使用某些"聪明"令牌的想法.超越了你应该避免使用HTTPS /加密的想法,因为"它很慢",过程密集等等.这是一个过程密集型,因为它是一种加密算法.确保用户数据和应用程序数据安全的必要性始终是您的首要任务.您不希望通知用户他们的数据已被泄露.

  • 典型的网络应用程序的绝佳答案.但我相信OP正在询问REST API服务器的身份验证选项.例如,如果您的REST API使用HTTP Basic Auth/Digest Auth,则不需要会话管理. (4认同)