【问题标题】:RESTful Authentication with Phone Number Verification Requirement带有电话号码验证要求的 RESTful 身份验证
【发布时间】:2014-12-10 04:15:30
【问题描述】:

当使用必须验证的电话号码执行身份验证时,如何处理 RESTful 身份验证?

例如,假设用户想要登录。用户将使用电话号码点击端点,然后将短信排队发送到该电话号码以进行验证。

理论上,这两个端点可能如下所示:

身份验证 [POST /users/authentication]

使用电话号码查找或创建用户,返回该用户,并将要发送到指定电话号码的文本消息排入队列(延迟)。

  • 请求(应用程序/json)

    {
        "phone_number": "4151111111"
    }
    
  • 响应 200(应用程序/json)

    {
        "id": "85165292-8cce-42a3-960a-ffbc7dac987b",
        "name": "James",
        "avatar_url": null,
        "phone_number": 4151111111
    }
    

组验证

用户提供短信中发送的验证码,以验证请求身份验证的用户是否有效。

验证 [POST /users/{id}/verification]

  • 请求(应用程序/json)

    {
        "phone_number_verification_code": "1234"
    }
    
  • 响应 200(应用程序/json)

    {
        "id": "85165292-8cce-42a3-960a-ffbc7dac987b",
        "name": "James",
        "avatar_url": null,
        "phone_number": 4151111111,
        "auth_token": "ff6828134dd6b2d288qcb8f381b0657c"
    }
    

以 RESTful 方式进行此验证的惯用方式是什么?动词正确吗?端点名称是否正确?我错过了什么吗?

【问题讨论】:

    标签: rest authentication restful-authentication rest-security


    【解决方案1】:

    问题中缺少一些信息。是否已经在服务器上创建了资源“用户”,只是要验证电话号码吗?

    假设“是”。以下方案对我来说看起来不错:-

    身份验证

    请求

    POST /users/<uid>/phones
    {
      “phone”: “4151111111”
    }
    

    添加新资源时应使用响应 201(已创建)。在这种情况下,会创建一个新的电话号码,因此应返回 201。

    阅读规范以获取更多信息http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5

    根据 REST 规范,POST 方法应添加子资源。而GET方法应该列出URI所代表的资源下的子资源。

    按照这些 REST 规范进行设计,对同一 URL 执行 GET 可能会返回电话号码列表。这不是强制性的,但根据 REST 语义它应该是这样的。所以一个 GET 请求/响应应该是这样的,

    请求

    GET /users/<uid>/phones
    

    响应 200 正常

    {
      “phones”: [
        {“phone”: “4151111111”, “verified”: “no”},
        {“phone”: “xxxxxxxxxx”, “verified”: “yes”},
        …
      ]
    }
    

    用于验证

    现在您已经在服务器上拥有一个由 URI (/users//phones/4151111111) 标识的资源。只是没有经过验证。要验证它,请直接向资源发送帖子消息。像这样

    请求

    POST /users/<uid>/phones/4151111111
    {
      “code”: “1234”
    }
    

    响应 200 正常。

    现在“电话”上的 GET 将返回“已验证”:“是”。像这样,

    请求

    GET /users/<uid>/phones
    

    响应 200 正常

    {
      “phones”: [
        {“phone”: “4151111111”, “verified”: “yes”},
        {“phone”: “xxxxxxxxxx”, “verified”: “yes”},
        …
      ]
    }
    

    如果尚未创建“用户”,那么您也可以为用户使用类似的语义。像这样。

    获取/用户

    POST /users,带有有效负载以添加新用户。响应 201(已创建)等

    更新

    如果用户存在或者是新用户,请求可能在 URL 中没有“用户”,像这样,

    POST /phones
    {
      “phone”: “4151111111”,
      "user": "James"
    }
    

    响应可能是 201(已创建),但我们还必须注意用户是否已经存在。当发送电话号码时,可以在数据库中搜索匹配的用户,并根据不同的条件返回这样的响应,

    案例1,用户不存在

    HTTP/1.1 200 OK
    
    {
       "rel": "/phones/4151111111",
       "phone": "4151111111",
       "verified": "no"
    }
    

    案例2,用户存在但手机未验证

    HTTP/1.1 200 OK
    
    {
       "rel": "/phones/4151111111",
       "phone": "4151111111",
       "verified": "no"
    }
    

    请注意,情况 1 和 2 的响应是相同的。情况 1 是在服务器上创建用户。

    案例 3,用户存在且手机已验证

    HTTP/1.1 200 OK
    
    {
       "rel": "/phones/4151111111",
       "phone": "4151111111",
       "verified": "yes"
    }
    

    如果情况 3 用户已经存在并且电话已经过验证;所以客户端应该发送一个 GET 请求,而不是再次发送带有验证码的 POST。客户端应该自动重定向而不是用户发起 POST。

    案例 4,电话已经存在,但与其他用户关联。在这种情况下,返回错误代码或根据您的应用程序要求。

    在响应中发送 URI 尊重 RESTful 样式的“按需代码”语义。客户无需事先知道在哪里进行验证。

    为了验证,现在客户端会将在文本消息中收到的代码 POST 到先前响应中返回的 URI。像这样,

    POST /phones/4151111111
    {
      “code”: “1234”
    }
    

    响应可能是 201(已创建),因为还添加了新电话或 200 以及所需的响应正文。

    【讨论】:

    • 感谢您的回答。我在问题中确实提到第一个端点将用于查找现有用户或创建新用户。据我了解,这不是非常 RESTful,但这是我需要处理的 UX 要求。
    • 对不起,我错过了这一点。我已经更新了我的答案并尝试适应创建用户点。
    猜你喜欢
    • 2021-04-03
    • 2020-01-28
    • 2018-10-30
    • 1970-01-01
    • 1970-01-01
    • 2019-11-03
    • 2023-03-05
    • 1970-01-01
    • 2017-10-17
    相关资源
    最近更新 更多