我必须制定计划来开发RESTful API(Python/Flask),以供将来的Web应用程序(Angularjs)和移动应用程序(iOS/Android)使用。

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

  • 使用Basic-Http-Auth并针对向API的每个请求通过网络以明文形式(但仍为https)发送用户名/密码。
  • 使用Digest-Auth,这是密码的哈希值,跟踪将是自动的。这将适用于Web应用程序,但是我无法确认iPhone和Android是否会原生支持此功能。如果他们这样做,那可能是一个简单的解决方案!
  • 使用自定义的HTTP header ,在身份验证成功后,我将在http header 中发送自定义的Auth字符串。但随后,我必须确保针对用户的每个请求都发送此身份验证代码。这与1)完全相同,不同之处在于不使用普通密码,并且验证码可以到期而没有任何风险。身份验证代码的跟踪也存在问题,不再像2)
  • 中那样自动执行
  • 使用OAuth是一个选项。但是它很难建立。如果没有更好的方法,那可能就是唯一的方法吗?
  • great article中所述保护API像Amazon S3一样安全。简而言之,他说服务器和客户端都将知道私钥,他们将使用私钥对通信进行哈希处理。就像黑帮握手一样,如果他知道黑帮握手,您将只相信送货员。有人问的评论更进一步:



  • 因此,换句话说,根本没有必要针对Web应用程序使用该方法。老实说,我也不知道该如何在移动设备上工作。用户下载了我们的应用程序,如何将私钥从iPhone发送到服务器?我转移它的那一刻,它将受到损害。

    我研究的越多,我就变得犹豫不决。

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

    最佳答案

    您似乎在混淆/合并两个不同的概念。我们开始谈论加密流量(HTTPS),然后开始谈论管理经过身份验证的 session 的不同方法。在安全的应用程序中,这些不是互斥的任务。 session 管理如何影响身份验证似乎也存在误解。基于此,我将提供有关Web应用程序/Web api session 管理,身份验证和加密的入门。

    介绍

    session 管理

    默认情况下,HTTP事务是无状态的。 HTTP未指定任何方法来让您的应用程序知道已从特定用户(已通过身份验证的用户)发送了HTTP请求。

    对于健壮的Web应用程序,这是 Not Acceptable 。我们需要一种方法来关联请求和跨多个请求的数据。为此,在向服务器发出初始请求后,需要为用户分配一个“ session ”。通常, session 具有发送给客户端的某种唯一ID。客户端随每个请求一起发送该 session ID,服务器使用在每个请求中发送的 session ID为用户正确准备响应。

    重要的是要记住,“ session ID”可以称为许多其他事物。其中的一些示例是: session token , token 等。为保持一致性,我将在此响应的其余部分中使用“ session ID”。

    来自客户端的每个HTTP请求都需要包含 session ID;这可以通过许多方式来完成。流行的例子有:

  • 它可以存储在cookie中-当前域的cookie会在每次请求时自动发送。
  • 可以在URL上发送-每个请求都可以在URL上发送 session ID,不建议使用,因为 session ID会保留在客户端历史记录中
  • 可以通过HTTP header 发送-每个请求都需要指定 header

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

    请记住,通知客户端其 session ID的HTTP响应以及包含该 session ID的客户端请求是完全纯文本且100%不安全的,这一点非常重要。为了解决这个问题,所有HTTP流量都需要加密。这就是HTTPS的来历。

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

    身份验证

    身份验证是我们将 session 链接到系统中特定用户的位置。这通常由登录过程处理,在该过程中,用户提供了凭据,这些凭据经过了验证,然后我们将 session 链接到系统中的特定用户记录。

    用户又通过访问控制列表和访问控制项(ACL和ACE)与细粒度访问控制的特权相关联。这通常称为“授权”。大多数系统始终同时具有身份验证和授权。在某些简单的系统中,所有通过身份验证的用户都是平等的,在这种情况下,您将不会获得通过简单例份验证的授权。有关此问题的更多信息超出了此问题的范围,但请考虑阅读有关ACE/ACL的信息。

    可以将特定 session 标记为以不同方式表示经过身份验证的用户。
  • 他们的 session 数据存储在服务器端,可以存储他们的用户ID/其他标志,该标志表示使用已通过特定用户身份认证
  • 另一个用户 token 可以像 session ID一样发送到客户端(通过未加密的HTTP与发送未加密的 session ID一样不安全)

    两种选择都可以。通常,这取决于您使用的技术及其默认提供的功能。

    客户端通常会启动身份验证过程。这可以通过将凭证发送到特定的网址(例如yoursite.com/api/login)来完成。但是,如果我们想成为“RESTful”,我们通常会使用一些名词来引用资源并执行“create”操作。这可以通过要求将凭证的POST到yoursite.com/api/authenticatedSession/来完成。想法是创建一个经过身份验证的 session 。大多数站点只是将凭据发布到/api/login等。这与“真实的”或“纯净的” RESTful理想背道而驰,但是大多数人发现这是一个更简单的概念,而不是将其视为“创建经过身份验证的 session ”。

    加密

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

    这样做的原因是,如果您对用户进行身份验证,与他们共享一个 secret (他们的 session ID等),然后开始用纯HTTP声明该 secret ,那么他们的 session 可能会被中间人攻击所劫持。黑客将等待流量通过观察到的网络并窃取 secret (因为其纯文本通过HTTP),然后启动与您的服务器的连接,并假装自己是原始客户端。

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

    如果需要在HTTP和HTTPS部分之间拆分站点,则必须确保HTTP通信量不发送或接收 session ID或用于管理用户身份验证状态的任何 token 。同样重要的是,不要在非HTTPs请求/响应内发送敏感的应用程序数据。

    在Web应用程序/API中保护数据安全的唯一方法是对流量进行加密。

    您的主题一个接一个

    Basic-Http-Auth
  • 身份验证:是
  • session 管理:否
  • 加密:否

  • 这是仅通过Web资源进行身份验证的方法。基本身份验证通过URL标识的资源对使用进行身份验证。这是由Apache HTTP Web Server最流行地使用基于.htaccess的目录/位置身份验证来实现的。凭据必须随每个请求一起发送;客户通常对用户透明地进行处理。

    其他系统可以将基本身份验证用作身份验证的方式。但是,利用Basic-Http-Auth的系统正在提供身份验证和 session 管理,而不是Basic-Http-Auth本身。
  • 这不是 session 管理。
  • 这不是加密;内容和凭据接近100%纯文本
  • 这不保护应用程序的HTTP请求/响应的内容。

  • 摘要验证
  • 身份验证:是
  • session 管理:否
  • 加密:否

  • 这与Basic-Http-Auth完全相同,只是增加了一些简单的MD5摘要。不应该依靠这种摘要来代替使用加密。
  • 这不是 session 管理。
  • 这不是加密;摘要很容易被破坏
  • 这不保护应用程序的HTTP请求/响应的内容。

  • OAuth
  • 身份验证:是
  • session 管理:否
  • 加密:否

  • OAuth只允许您让外部服务验证凭据。之后,由您来管理/处理对OAuth提供者的身份验证请求的结果。
  • 这不是 session 管理。
  • 这不是加密;您的网站流量仍然是纯文本。由于HTTPS限制,身份验证过程将是安全的,但是您的应用程序仍然容易受到攻击。
  • 这不保护应用程序的HTTP请求/响应的内容。

  • 匪徒握手/自定义HTTP header
  • 身份验证:是,可能是
  • session 管理:是,可能是
  • 加密:否

  • “自定义HTTP header ”是“流氓握手”的一种;因此,我将使用同一部分来讨论它们。唯一的区别是“自定义HTTP header ”指定了hanshake( session ID, token ,用户身份验证 token 等)的存储位置(即HTTP header 中)。

    重要的是要注意,这些都没有指定将如何处理身份验证,也没有指定将如何处理 session 管理。它们本质上描述了 session ID/身份验证 token 的存储方式和位置。

    身份验证需要由您的应用程序或第三方(例如OAuth)处理。 session 管理也将仍然需要实现。有趣的是,您可以根据需要选择将两者合并。
  • 这不是加密;您的网站流量仍然是纯文本。如果使用OAuth,则由于HTTPS限制,身份验证过程将是安全的,但是您的应用程序仍然容易受到攻击。
  • 这不保护应用程序的HTTP请求/响应的内容。

  • 你需要做什么

    ...我强烈建议您确保您了解安全的健壮Web应用程序需要以下条件:
  • 加密(HTTPS几乎是您唯一的选择)
  • session 管理
  • 身份验证/授权

  • 授权依赖于身份验证。身份验证依赖于 session 管理和加密,以确保 session 不会被劫持,并且凭据不会被拦截。

    flask 登录

    我认为您应该研究flask-login来避免重新实现。我个人从未使用过它(我将金字塔用于python中的Web应用程序)。但是,我已经看到它在Web应用程序/python板中之前提到过。它同时处理身份验证和 session 管理。通过HTTPS抛出您的Web api/应用程序,并且您拥有全部三个(加密, session 管理和用户身份验证)。

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

    如果可能的话,如果您不了解如何编写身份验证过程,请先尝试了解黑客如何使用基于模式的攻击,定时攻击等,然后再尝试尝试。

    ,请加密您的流量

    ...超越了您可以避免将HTTPS与“聪明” token 一起使用的想法。超越了您应该避免使用HTTPS/加密的想法,因为它“慢”,过程密集等。它是过程密集的,因为它是一种加密算法。确保用户数据和应用程序数据的安全性始终是您的最高优先事项。您不想 panic 地通知您的用户其数据已泄露。

    09-25 17:49
    查看更多