如何使用多个OAUTH提供商安全地在App Engine上注册用户? [英] How to securely register users on App Engine using multiple OAUTH providers?

查看:197
本文介绍了如何使用多个OAUTH提供商安全地在App Engine上注册用户?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想讨论一个常见的情况:应用程序想要授权使用多个OAUTH提供商(如Facebook,Google+或Twitter)的用户。



本质上这个问题两年前在这里被问到这里移动API验证使用200的X- 200 X- 200 200 200 200 X- 200 200 X- 200 200 X- 200 200 X- 200 200 X- (我将使用Facebook作为OAUTH2提供商的一个例子,所以这不会变得太通用。)



本质上,用户注册的工作原理如下:OAUTH / OAUTH2提供商通常提供一个工作流程,其中通过移动设备上的AccountManager或一个登录对话框(例如使用Facebook登录)按钮从提供商获取(大多是短命的)令牌。然后,令牌通过调用REST端点(在正文中或作为附加标题,从不在URL中)发送到App Engine。



提供者的AppId和AppSecret (这里:Facebook)存储在App Engine和App Engine中,将它们添加到令牌中,然后将其返回到Facebook,以换取(长寿命)令牌。





此时,我们可以尝试在我们的数据存储中查找用户,并注册失败(或者默认登录用户),如果它已经存在,或者创建一个记录。 p>

直到这里,我确定我在正确的轨道上。现在出现问题:



我们来看看这个数据存储区。假设我们有两个实体:


  1. 用户实体,我们自己的系统中的每个用户都以唯一的用户ID进行注册。 >
  2. 帐户实体,其中每个帐户都已注册,userId字段指向用户实体。

在关系数据库术语中,我们假设用户和帐户之间的关系为1:n。



对于系统中的每个用户,我们保留用户记录。在上面的例子中,我们可能有两个帐户:Facebook和Google,它们都指向用户,并且使用独特的Facebook或Google ID /电子邮件作为帐户标识符。



从技术上讲,应用程序可能会在后续请求中使用Facebook或Google帐户。 X-45454545新新新新新旗新新旗新新旗新新旗新旗新旗新新旗旗新新旗新旗新新旗旗新新旗新新200新新新200新200新新200新200新新200新新200新新200新新200新新200新新200新新200新新200新新200新新200新新200新新200新新200新新200新新200新新200新新200新新200新新200新我们可以要求提供者做到这一点,但也不会有任何意义。此外,我们必须将提供商的帐户ID转换为每个请求的自己的用户ID。



为了解决这个问题,我最有可能创建自己的令牌或设置我们自己的OAUTH提供商,它创建一个由我们自己的系统签名的令牌,唯一的用户ID被用作标识符,并且仅在随后的请求中使用该标记。




  • 这是一个很好的方法吗?有人使用不同的更好的工作流程吗?有没有人看到这种设计的安全漏洞?



本质上它适用于Google的端点系统,但Google只能针对自己的系统进行身份验证,所以如果我们要使用更多的提供商提供登录,我们将需要解决这个问题,除非有人知道我们可以保持两者的工作流程,但是我们有这个问题,我们可以/应该只添加一个令牌授权标题和REST原则不鼓励我们使用自定义标头来运送更多的令牌。

解决方案

当您的应用程序验证用户时,将对象存储在包含已被用于访问应用程序的oauth提供程序的会话中,以及可选的用于后续请求的令牌。



现在你可以在每次调用服务器时检查此对象。如果对象不存在 - 用户未通过身份验证,则重定向到登录页面。如果一个对象存在,请拿一个令牌并使用它。



我对多个身份验证选项使用了类似的方法,而不仅仅是oauth。除非我在用户认证后不需要存储令牌 - 我在应用程序中没有使用它。


I would like to discuss a common scenario: An app wants to authorize users using multiple OAUTH providers, such as Facebook, Google+ or Twitter.

Essentially this question has been asked two years ago here Mobile API Authentication Using Existing Web App with Multiple OAuth Providers and stays unanswered, so I will elaborate a bit further. (I will use Facebook as an example for the OAUTH2 provider, so this does not become too generic.)

Essentially, user registration works like this: OAUTH/OAUTH2 providers typically provide a workflow where a (mostly short-lived) token is obtained from a provider either via the AccountManager on the mobile device or a login dialog such as the "Login with Facebook" button. The token is then shipped to App Engine by calling a REST endpoint (either in the body or as an additional header, never in the URL).

The provider's AppId and AppSecret (here: Facebook) are store on App Engine and App Engine adds these to the token, then ships it back to Facebook in exchange for a (long-lived) token.

At this point both, client app and App Engine app have certainty that the user has been previously authenticated by Facebook. Also, if Endpoints Authentication is used to authenticate the call, App Engine probably has the Google credentials of the user and/or the ClientId of the app, and Google guarantees that the request has been made from the correct client app.

At this point, we can try to find the user in our datastore and let registration fail (or silently sign in the user) if it already exists, or otherwise create a record.

Until here I am pretty sure I'm on the right track. Now comes the problem:

Let's look at the datastore for this. Let's assume we have two entities:

  1. User entity, where each user in our own system is registered under a unique user id.
  2. Account entity, where each account is registered and where a userId field points to the User entity.

In relational database terms, we would say we have a 1:n relationship between User and Account.

For each User in our system, we keep a User record. In above example, we may have two accounts: Facebook and Google, which both point to the user and where the unique Facebook or Google id/email is used as account identifier.

Technically it would now be possible that the app uses the Facebook or Google account on subsequent requests. But we would have to store and look up the 3rd-party token on each request because we cannot decrypt it ourselves. We could ask the provider to do this, but that wouldn't make much sense either. Plus we would have to translate the provider's Account id to our own User id on each request.

To solve this problem I would most probably either create our own token or set up our own OAUTH provider which creates a token signed by our own system, and where the unique User id is used as identifier, and only use that token during subsequent requests.

  • Is this a good approach? Is anybody using a different better workflow? Does anybody see security flaws with this design?

Essentially it works around Google's endpoints system, but Google can only authenticate against their own systems, so if we want to offer sign-in using further providers, we will need to work around this, except if anybody knows a workflow where we can keep both, but then we have the problem that we can/should only add a single token in the "Authorization" header and REST principles discourage us to use custom headers to ship more tokens.

解决方案

When your app authenticates a user, store an object in a session which contains an oauth provider that has been used to access the app and, optionally, a token to be used for subsequent requests.

Now you can check for this object in every call to the server. If the object is not present - a user is not authenticated, redirect to the login page. If an object is present, take a token and use it.

I use a similar approach for multiple authentication options, not only oauth. Except I don't need to store a token after a user is authenticated - I have no use for it within the app.

这篇关于如何使用多个OAUTH提供商安全地在App Engine上注册用户?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆