Python Social Auth,Google和刷新令牌

时间:2018-02-08 00:13:04

标签: python django oauth-2.0 google-oauth2 python-social-auth

在个人项目中,我尝试使用Django作为我的前端,然后允许用户以特定形式输入的数据被复制到谷歌表。

Google自己的文档建议使用现已弃用的https://github.com/google/oauth2client,并且文档尚未更新。有了这个,我开始尝试使用Python Social AuthGspread。为了让Gspread能够正常运行,我需要能够不仅传递访问令牌而且还传递刷新令牌。然而,Python Social Auth不会将刷新令牌与其他数据"持久保存。查看保留的数据和路由到的URL,在我看来它更像是通过Google +路由的地方。

我的Django设置文件中有以下配置:

AUTHENTICATION_BACKENDS = (
    'social_core.backends.google.GoogleOAuth2',
    'django.contrib.auth.backends.ModelBackend',
)

SOCIAL_AUTH_PIPELINE = (
    'social_core.pipeline.social_auth.social_details',
    'social_core.pipeline.social_auth.social_uid',
    'social_core.pipeline.social_auth.social_user',
    'social_core.pipeline.user.get_username',
    'social_core.pipeline.user.create_user',
    'social_core.pipeline.social_auth.associate_user',
    'social_core.pipeline.social_auth.load_extra_data',
    'social_core.pipeline.user.user_details',
    'social_core.pipeline.social_auth.associate_by_email',
)    

SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = '...'
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = '...'
SOCIAL_AUTH_GOOGLE_OAUTH2_SCOPE = ['https://www.googleapis.com/auth/spreadsheets']
  • 有没有更好的方式来访问谷歌表?
  • 我是否认为PSA或谷歌会将我重定向到Google+身份验证流程而不是Google Oauth2?
  • 如果没有,那么必须更改哪些内容以便Python Social Auth保留刷新令牌?

3 个答案:

答案 0 :(得分:1)

只需在您的settings.py中提供它:

SOCIAL_AUTH_GOOGLE_OAUTH2_AUTH_EXTRA_ARGUMENTS = { 'access_type': 'offline', 'hd': 'stayabode.com', 'approval_prompt':'force' } 记住,{'approval_prompt' : 'force'}会强制用户选择Gmail帐户,这样您将获得刷新令牌。

答案 1 :(得分:1)

您可以使用变量向OAuth2提供程序发送额外的参数

SOCIAL_AUTH_<PROVIDER>_AUTH_EXTRA_ARGUMENTS

对于Google,您可以看到它们接受in their documentation (scroll down to "parameters")的其他参数。我们正在寻找的是access_type

access_type :指示当用户不在浏览器中时,您的应用程序是否可以刷新访问令牌。有效的参数值是在线(默认值)和离线。

因此,我们可以将以下内容添加到settings.py中,以表明我们要接收刷新令牌:

SOCIAL_AUTH_GOOGLE_OAUTH2_EXTRA_ARGUMENTS = {"access_type: offline"}

来自EXTRA_ARGUMENTS的结果将存储在extra_data中,因此可以按以下方式访问刷新令牌:

refresh_token = user.social_auth.get(provider="google-oauth2").extra_data["refresh_token"]

一种可能的解决方案是通过向社交身份验证管道添加自定义功能,在UserProfile模型中将刷新令牌与用户一起存储:

  1. 创建模型
# models.py

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="profile")
    refresh_token = models.CharField(max_length=255, default="")
  1. 添加用于访问存储刷新令牌的功能
# pipeline.py

from .models import UserProfile

def store_refresh_token(user=none, *args, **kwargs):
    extra_data = user.social_auth.get(provider="google-oauth2").extra_data
    UserProfile.objects.get_or_create(
        user=user, defaults={"refresh_token": extra_data["refresh_token"]}
    )
  1. 将我们的新功能添加到social-auth管道中。
# settings.py

...

SOCIAL_AUTH_PIPELINE = (
    ...
    "my-app.pipeline.store_refresh_token"
)  

SOCIAL_AUTH_GOOGLE_OAUTH2_SCOPE = [
    'https://www.googleapis.com/auth/spreadsheets'
    # any other scopes you need
]

...

令牌现在与用户一起存储,可用于初始化工作表客户端或您需要的其他任何内容。

答案 2 :(得分:0)

python-social-auth确实会使用Google+平台的某些内容,至少使用API​​来检索有关用户填写帐户的详细信息。

从您的设置中,我看到底部有associate_by_email,此时此刻它没有用,因为用户已经创建,如果您真的打算使用它,它必须是在create_user之前,您可以查看DEFAULT_PIPELINE作为参考。

要从谷歌获得refresh_token,您需要告诉它您需要一个,为此您需要设置offline访问类型:

SOCIAL_AUTH_GOOGLE_OAUTH2_AUTH_EXTRA_ARGUMENTS = {
  'access_type': 'offline'
}

通过该设置,Google会为您提供refresh_token,并会自动存储在extra_data