在个人项目中,我尝试使用Django作为我的前端,然后允许用户以特定形式输入的数据被复制到谷歌表。
Google自己的文档建议使用现已弃用的https://github.com/google/oauth2client,并且文档尚未更新。有了这个,我开始尝试使用Python Social Auth和Gspread。为了让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']
答案 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
模型中将刷新令牌与用户一起存储:
# 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="")
# 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"]}
)
# 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
。