python教程—我如何使用Django OAuth工具包与Python Social Auth?-Python实用宝典

python教程—我如何使用Django OAuth工具包与Python Social Auth?

我正在使用Django Rest框架构建一个API。稍后,这个API将被iOS和Android设备使用。我希望允许我的用户注册oauth2提供商,如Facebook和谷歌。在这种情况下,他们根本不需要在我的平台上创建一个帐户。但是,当没有Facebook/谷歌帐户时,用户也应该能够注册,因为我使用的是django-oauth-toolkit,所以我有自己的oau2提供程序。

我正在使用Django Rest框架构建一个API。稍后,这个API将被iOS和Android设备使用。我希望允许我的用户注册oauth2提供商,如Facebook和谷歌。在这种情况下,他们根本不需要在我的平台上创建一个帐户。但是,当没有Facebook/谷歌帐户时,用户也应该能够注册,因为我使用的是Django-oauth-toolkit,所以我有自己的oau2提供程序。

对于外部提供者,我使用python-social-auth,它可以很好地工作,并自动创建用户对象。

我希望客户端通过使用承载令牌进行身份验证,这对于与我的提供者(Django -oauth-toolkit为Django REST框架提供了身份验证方案和权限类)注册的用户非常有效。

然而,python-social-auth只实现基于会话的身份验证,因此没有直接的方法来代表外部oauth2提供者注册的用户发出经过身份验证的API请求。

如果我使用由Django-oauth-toolkit生成的access_token,执行这样的请求:

    curl -v -H "Authorization: Bearer <token_generated_by_django-oauth-toolkit>" http://localhost:8000/api/

但是,由于Django REST框架没有对应的身份验证方案,而且python-social-auth提供的AUTHENTICATION_BACKENDS只适用于基于会话的身份验证,所以下面的方法不适用:

    curl -v -H "Authorization: Bearer <token_stored_by_python-social-auth>" http://localhost:8000/api/

在使用python-social-auth进行身份验证之后,使用Django REST框架提供的可浏览API就可以了,只有没有会话cookie的API调用才不能工作。

我想知道解决这个问题的最好办法是什么。在我看来,我基本上有两种选择:

答:当用户与外部oauth2提供程序(由python-social-auth处理)注册时,挂钩到流程中以创建oauth2_provider.models。AccessToken并继续使用“oauth2_provider.ext.rest_framework”。OAuth2Authentication',现在还对在外部提供者注册的用户进行身份验证。这里建议这样做:
< a href = " https://groups.google.com/d/msg/django-rest-framework/ACKx1kY7kZM/YPWFA2DP9LwJ " rel = " noreferrer " > https://groups.google.com/d/msg/Django-rest-framework/ACKx1kY7kZM/YPWFA2DP9LwJ < / >

使用python-social-auth进行API请求认证。通过编写自定义后端并使用register_by_access_token,我可以让自己的用户进入python-social-auth。但是,由于API调用不能使用Django会话,这意味着我必须为Django Rest框架编写一个身份验证方案,该方案使用python-social-auth存储的数据。关于如何做到这一点,可以在这里找到一些建议:
< br >
< a href = " http://psa.matiasaguirre.net/docs/use_cases.html signup-by-oauth-access-token”rel = " noreferrer " > http://psa.matiasaguirre.net/docs/use_cases.html signup-by-oauth-access-token < / > < br >
< a href = " http://blog.wizer.fr/2013/11/angularjs-facebook-with-a-django-rest-api/ " rel = " noreferrer " > http://blog.wizer.fr/2013/11/angularjs-facebook-with-a-Django-rest-api/ < / > < br >
< a href = " http://cbdev.blogspot.it/2014/02/facebook-login-with-angularjs-django。html " rel = " http://cbdev.blogspot.it/2014/02/facebook-login-with-angularjs-django.html noreferrer " > < / > < br >
但是,我对python-social-auth的理解是,它只在登录时验证令牌,然后依赖Django会话。这将意味着我将不得不找到一种方法,以防止python-social-auth做整个oauth2-flow为每一个无状态的API请求而核对的数据存储在数据中,而不是优化查询因为它是存储为JSON(我可以用UserSocialAuth.objects.get (extra_data__contains =))。
< br >
我还必须检查访问令牌的范围,并使用它们检查权限,这是Django-oauth-toolkit已经做过的(TokenHasScope、required_scope等)。

目前,我倾向于使用选项A,因为Django -oauth-toolkit提供了与Django Rest框架的良好集成,并且我已经从盒子里得到了我需要的所有东西。惟一的缺点是,我必须将python-social-auth检索到的access_token“注入”到Django-oauth-toolkit的AccessToken模型中,这感觉有点不对,但可能是迄今为止最简单的方法。

有人反对这样做吗?或者有人用不同的方法解决过同样的问题吗?我是不是错过了一些显而易见的东西,让我的生活变得比必要的还要艰难?
如果有人已经将Django-oauth-toolkit与python-social-auth和外部oauth2提供者集成在一起,我将非常感谢您提供的一些建议或意见。

回答

实现OAuth的许多困难都归结于理解授权流应该如何工作。这主要是因为这是登录的“起点”,当使用第三方后端(使用类似Python Social Auth的东西)时,实际上是做了两次:一次用于您的API,一次用于第三方API。

使用API和第三方后端授权请求

您需要通过的认证流程为:

我如何使用Django OAuth工具包与Python Social Auth?

Mobile App -> Your API : Authorization redirect
Your API -> Django Login : Displays login page
Django Login -> Facebook : User signs in
Facebook -> Django Login : User authorizes your API
Django Login -> Your API : User signs in
Your API -> Mobile App : User authorizes mobile app

我在这里使用“Facebook”作为第三方后端,但是这个过程对于任何后端都是一样的

从您的移动应用程序的角度来看,您只是重定向到Django OAuth Toolkit提供的/authorize url 。从那里,移动应用程序等待回调url到达,就像在标准OAuth授权流中一样。几乎所有其他的东西(Django登录、社交登录等等)都是由Django OAuth工具包或Python社交Auth在后台处理的。

这也将与您使用的几乎所有OAuth兼容,并且无论使用什么第三方后端,授权流都将工作相同。它甚至可以处理(常见的)情况,您需要能够支持Django的身份验证后端(电子邮件/用户名和密码)以及第三方登录。

我如何使用Django OAuth工具包与Python Social Auth?

Mobile App -> Your API : Authorization redirect
Your API -> Django Login : Displays login page
Django Login -> Your API : User signs in
Your API -> Mobile App : User authorizes mobile app

同样重要的是,移动应用程序(它可以是任何OAuth客户机)从未接收到Facebook/第三方OAuth令牌。这非常重要,因为它确保您的API充当OAuth客户机和您用户的社交帐户之间的中介。

我如何使用Django OAuth工具包与Python Social Auth?

Mobile App -> Your API : Authorization redirect
Your API -> Mobile App : Receives OAuth token
Mobile App -> Your API : Requests the display name
Your API -> Facebook : Requests the full name
Facebook -> Your API : Sends back the full name
Your API -> Mobile App : Send back a display name

否则,OAuth客户机将能够绕过您的API,并代表您向第三方API发出 请求。

我如何使用Django OAuth工具包与Python Social Auth?Mobile App -> Your API : Authorization redirect
Your API -> Mobile App : Receives Facebook token
Mobile App -> Facebook : Requests all of the followers
Facebook -> Mobile App : Sends any requested data

您将注意到,此时您将失去对第三方令牌的所有控制。这尤其危险,因为大多数令牌都可以访问广泛的数据,这为滥用打开了大门,并最终以您的名字访问。最有可能的是,那些登录到您的API/网站的用户并不打算与OAuth客户端共享他们的社交信息,而是希望您将该信息保持私有(尽可能多),但是相反,您将该信息公开给所有的用户。

对API的请求进行身份验证

当移动应用程序使用您的OAuth令牌您的API发出请求时,所有的身份验证都在后台通过Django OAuth Toolkit(或您的OAuth提供者)进行。只看到一个用户与您的请求相关联

我如何使用Django OAuth工具包与Python Social Auth?

Mobile App -> Your API : Sends request with OAuth token
Your API -> Django OAuth Toolkit : Verifies the token
Django OAuth Toolkit -> Your API : Returns the user who is authenticated
Your API -> Mobile App : Sends requested data back

这一点很重要,因为在授权阶段之后,如果用户来自Facebook或Django的身份验证系统,那么不会有什么影响。您的API只需要一个用户来使用,并且您的OAuth提供者应该能够处理令牌的身份验证和验证。

这与Django REST框架在使用会话支持的身份验证时对用户进行身份验证的方式没有太大区别。

我如何使用Django OAuth工具包与Python Social Auth?

Web Browser -> Your API : Sends session cookie
Your API -> Django : Verifies session token
Django -> Your API : Returns session data
Your API -> Django : Verifies the user session
Django -> Your API : Returns the logged in user
Your API -> Web Browser : Returns the requested data

所有这些都是由Django OAuth Toolkit处理的,并且不需要额外的工作来实现。

使用本地SDK

在大多数情况下,您将通过自己的网站对用户进行身份验证,并使用Python Social Auth处理所有事情。但是一个值得注意的例外是,当使用本机SDK时,身份验证和授权是通过本机系统处理的,这意味着您完全绕过了您的API 。对于需要与第三方登录的应用程序,或者根本不使用您的API的应用程序,这是非常棒的,但是当两者同时出现时简直是一场噩梦

这是因为您的服务器无法验证登录,并且被迫假设登录有效且真实,这意味着它绕过了Python Social Auth提供的所有安全性。

我如何使用Django OAuth工具包与Python Social Auth?

Mobile App -> Facebook SDK : Opens the authorization prompt
Facebook SDK -> Mobile App : Gets the Facebook token
Mobile App -> Your API : Sends the Facebook token for authorization
Your API -> Django Login : Tries to validate the token
Django Login -> Your API : Returns a matching user
Your API -> Mobile App : Sends back an OAuth token for the user

您将注意到,在身份验证阶段,这将跳过您的API,然后强制您的API对传入的令牌进行假设。但在某些情况下,这个风险可能值得,所以你应该在扔掉它之前评估一下。这是在quick和您的用户的本地登录之间的权衡,它们可能处理坏的或恶意的令牌

​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

本文由 Python实用宝典 作者:Python实用宝典 发表,其版权均为 Python实用宝典 所有,文章内容系作者个人观点,不代表 Python实用宝典 对观点赞同或支持。如需转载,请注明文章来源。
0

发表评论

意见反馈 在线咨询 简繁切换 返回评论 返回顶部