首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >REST上的用户注册/身份验证流

REST上的用户注册/身份验证流
EN

Stack Overflow用户
提问于 2015-01-10 12:37:55
回答 3查看 30.1K关注 0票数 38

我知道这不是第一次在StackOverflow中讨论这个话题,但是,我有一些问题我找不到答案,或者其他问题有相反的答案。

我正在做一个相当简单的REST (Silex-PHP),最初由一个SPA (骨干应用程序)使用。我不想评论这个问题中的所有几种身份验证方法,因为这个主题已经完全涵盖了。我将基本上为每个用户创建一个令牌,这个令牌将附加在每个需要SPA身份验证的请求中。所有Server事务将在HTTPS下运行。现在,我的决定是令牌不会过期。每个会话到期/令牌的令牌不符合REST的无状态状态,对吗?我知道有很大的安全改进空间,但这是我目前的工作范围。

我有一个令牌模型,因此在数据库中有一个带有FK到user_id的令牌表。我的意思是,令牌不是我的用户模型的一部分。

寄存器

我有一个POST /users (不需要身份验证),它在数据库中创建一个用户并返回新用户。这符合“一个请求一个资源”规则。然而,这使我产生了一些疑问:

  • 我的想法是,在创建新用户时,为用户创建一个新令牌,立即返回响应,从而改进UX。用户将立即能够开始使用web应用程序。但是,返回此类响应的令牌将打破只返回资源的规则。我应该一起提出两个请求吗?一个用于创建用户,另一个用于检索令牌,而不需要重新输入凭据?

  • 如果我决定与用户一起返回令牌,那么我相信POST /users会使API使用者感到困惑,然后就会出现POST /auth//users之类的东西。再一次,我不喜欢这个想法,因为它涉及一个动词。我非常喜欢this answer中提供的简单性。但是,我需要同时处理两个请求,一个POST /users和POST /tokens。同时处理两个请求有何错误?如果同时发送两个请求,我将如何确切地将令牌附加到某个用户?

目前,我的流程如下所示:

代码语言:javascript
复制
1. Register form makes a POST /users request
2. Server creates a new user and a new token, returns both in the response (break REST rule)
3. Client now attaches token to every Request that needs Authorization

令牌永远不会过期,保持静止无国籍状态。

电子邮件验证

当前的大多数can应用都需要电子邮件验证,而不破坏用户的UX,即用户注册后可以立即使用can应用程序。另一方面,如果我像上面建议的那样返回注册请求的令牌,用户将立即访问每个资源,而无需验证电子邮件。

通常,我会选择以下工作流:

代码语言:javascript
复制
1. Register form sends POST /users request.
2. Server creates a new user with validated_email set to false and stores an email_validation_token. Additionally, the server sends an email generating an URL that contains the email_validation_token. 
3. The user clicks on the URL that makes a request: For example POST /users/email_validation/{email_validation_token}
4. Server validates email, sets validated_email to true, generates a token and returns it in the response, redirecting the user to his home page at the same time.

这看起来太复杂了,完全破坏了UX。你做得如何?

登录

这很简单,现在我是这样做的,所以如果我做错了,请纠正我:

代码语言:javascript
复制
1. User fills a log in form which makes a request to POST /login sending Basic Auth credentials.
2. Server checks Basic Auth credentials and returns token for the given user.
3. Web app attached the given token to every future request.

登录是一个动词,因此违反了REST规则,每个人似乎都同意这样做。

注销

为什么每个人似乎都需要一个/auth/auth端点?在我看来,点击web应用程序中的“注销”基本上应该从应用程序中删除令牌,而不是在进一步的请求中发送它。服务器在这方面不起作用。

由于令牌可能保存在localStorage中,以防止在可能的页面刷新中丢失令牌,注销也意味着从localStorage中删除令牌。但是,这并不影响服务器。我了解需要POST /logout的人基本上都在使用会话令牌,这再次打破了REST的无状态状态。

别忘了我

我明白,记住,我基本上是指将返回的令牌保存到localStorage中,或者在我的情况下不是。是这样的吗?

如果你建议进一步阅读这个话题,我会非常感激的。谢谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-06-04 20:51:02

寄存器

每个会话到期/令牌的令牌不符合REST的无状态状态,对吗?

不,这没什么不好的。许多HTTP身份验证方案确实有过期的令牌。OAuth2在REST服务中非常流行,许多OAuth2实现迫使客户机不时刷新访问令牌。

我的想法是,在创建新用户时,为用户创建一个新令牌,立即返回响应,从而改进UX。用户将立即能够开始使用web应用程序。但是,返回此类响应的令牌将打破只返回资源的规则。我应该一起提出两个请求吗?一个用于创建用户,另一个用于检索令牌,而不需要重新输入凭据?

通常,如果您按照REST最佳实践创建了一个新资源,则不会返回类似这样的帖子。这么做会让电话更像RPC所以我同意你的观点.这不是完美的RESTful。我将提供两种解决方案:

  1. 忽视这一点,打破最佳实践。在这种情况下,也许这是最好的,如果它们更有意义的话,做例外有时是最好的选择(经过仔细的考虑)。
  2. 如果你想成为更多的RESTful,我会提供一个替代方案。

让我们假设您想使用OAuth2 (不错的主意!)。OAuth2 API并不是真正的RESTful,原因有很多。我认为最好还是使用一个定义良好的身份验证API,而不是为了成为RESTful而滚动自己的验证API。

这仍然给您留下了在API上创建用户的问题,并且响应这个(POST)调用,返回一个可以用作访问/刷新令牌的秘密。

我的选择如下:

--您不需要有一个用户来启动会话

相反,您可以做的是在创建用户之前启动会话。这保证了以后的任何电话,你都知道你在和同一个客户说话。

如果启动OAuth2进程并接收访问/刷新令牌,则只需在/users上执行经过身份验证的POST请求即可。这意味着您的系统需要了解2种类型的经过身份验证的用户:

  1. 使用用户名/密码登录的用户(`grant_type = passsword1)。
  2. 登录“匿名”并打算在事实发生后创建用户的用户。(grant_type = client_credentials)。

创建用户后,可以使用新创建的用户实体分配先前的匿名会话,因此创建后不需要进行任何访问/刷新令牌交换。

电子邮件验证

你们两人的建议都是:

  • 在电子邮件验证完成之前,防止用户使用应用程序。
  • 允许用户立即使用应用程序。

都是通过申请完成的。哪一个更合适,真正取决于您的应用程序和什么是对您最好的。是否存在与用户开始使用他们不拥有的电子邮件的帐户相关的风险?如果没有,那么允许用户立即进入可能是好的。

这里有一个您不想这样做的例子:如果您系统的其他成员使用电子邮件地址添加用户作为朋友,则电子邮件地址是一种身份类型。如果你不强迫用户验证他们的电子邮件,这意味着我可以代表另一个电子邮件地址的人。这类似于能够收到邀请,等等。这是一个攻击矢量吗?然后,您可能需要考虑阻止用户使用应用程序,直到电子邮件被验证为止。

您还可以考虑只阻止应用程序中某些可能对电子邮件地址敏感的功能。在前面的示例中,在电子邮件验证之前,您可以防止人们看到来自其他用户的邀请。

这里没有正确的答案,这取决于你打算如何使用电子邮件地址。

登录

请使用OAuth2。您描述的流程已经非常接近于OAuth2的工作方式。再往前走一步,实际使用OAuth2。这是非常棒的,一旦您克服了理解协议的最初障碍,您会发现仅仅实现API中您特别需要的部分比您想象的要容易,而且相当简单。

大多数PHP服务器实现都不是很好。他们做的太多了,有点难以整合。滚动你自己的并不是那么困难,你已经相当接近建立类似的东西。

注销

您可能需要注销端点的两个原因是:

  1. 如果您使用基于cookie/会话的身份验证,并希望告诉服务器忘记会话。听起来这对你来说不是问题。
  2. 如果您想让服务器在访问/刷新令牌之前过期。是的,您可以将它们从本地存储中删除,这可能就足够了。迫使他们在服务器端到期可能会给你一点额外的信心。如果有人能够MITM您的浏览器,现在可以访问您的令牌?我可能想要快速注销和过期所有现有的令牌。这是一个边缘的情况,我个人从来没有这样做过,但这可能是你想要的原因之一。

,记住我,

是的,用本地存储器实现“记住我”听起来是个好主意。

票数 19
EN

Stack Overflow用户

发布于 2018-12-27 22:08:44

我最初采用的是/LOGON/LOGOUT方法。我开始探索/PRESENCE。这似乎有助于我将了解某人的身份和身份验证结合起来。

代码语言:javascript
复制
0 = Offline
1 = Available
2 = Busy

Offline到其他任何东西都应该包括初始验证(也就是需要用户名/密码)。为此您可以使用PATCHPUT (取决于您如何看待它)。

票数 0
EN

Stack Overflow用户

发布于 2015-03-31 11:55:02

您是对的,REST不允许会话,因此不需要登录或退出REST服务,而/login、/logout不是名词。

对于身份验证,您可以使用

  1. SSL上的基本认证
  2. 摘要认证
  3. OAuth 2
  4. HMAC等

我喜欢使用公钥和私钥HMAC。

私钥永远不会通过网络传输,我也不在乎公钥。公钥将用于使持有api密钥的用户特定操作。

私钥将由客户端应用程序和服务器知道。私钥将用于创建签名。使用私钥生成签名令牌,并将密钥添加到标头中。服务器还将生成签名并验证握手请求。

代码语言:javascript
复制
Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b

现在你怎么拿到私钥?你必须手动操作,就像你把facebook、twitter或google键放在你的应用程序上一样。

但是,在某些情况下,您也可以像Amazon一样只返回一次不推荐的密钥。它们在注册响应时提供"AWS秘密访问密钥“。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27876306

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档