TL; DR:是否可以不存储(Google / Facebook)OAuth2访问令牌,而是在每次登录时请求新令牌?
我会解释:
要将社交登录名(“使用Google / Facebook登录”)添加到Django应用中,您必须拥有Python Social Auth。至少对我而言,它的问题在于它比我想要的复杂得多,需要大量配置,在数据库中创建其他表,并且总体上感觉很多我不理解的活动部分完成一个非常简单的任务。
所以,我读了一些关于Google's和Facebook's流的信息,它们很简单:
然后:
现在可以丢弃访问令牌,因为只需要将Google / Facebook登录名转换为实际的电子邮件(由他们验证)即可,该电子邮件仅用作 用户标识符-否通过不同的社交服务登录时,由于帐户不同而造成的更多混乱;没有其他表格;没有不必要的复杂性。
这是代码,只是为了显示所需的内容:
# views.py
def login_view(request):
return render(request, 'login.html', {
'google_url': 'https://accounts.google.com/o/oauth2/v2/auth?' + urllib.parse.urlencode({
'client_id': GOOGLE_ID,
'redirect_uri': request.build_absolute_uri(reverse('oauth_google')),
'scope': 'profile email',
'response_type': 'code',
}),
}) # use this url in the template as a social login
def oauth_google(request):
code = request.GET['code']
response = requests.post('https://www.googleapis.com/oauth2/v4/token', {
'code': code,
'client_id': GOOGLE_ID,
'client_secret': GOOGLE_SECRET,
'redirect_uri': request.build_absolute_uri(reverse('oauth_google')),
'grant_type': 'authorization_code',
}).json()
id_token = response['id_token']
response = requests.get('https://www.googleapis.com/oauth2/v3/tokeninfo', {
'id_token': id_token,
}).json()
email = response['email']
user = User.objects.filter(username=email).first()
if not user:
user = User(username=email)
user.save()
auth.login(request, user)
return redirect('index')
# urls.py
urlpatterns = [
...
path('oauth/google', views.oauth_google, name='oauth_google'),
]
我的问题是:我想念什么?如果真的那么简单,为什么我在网上的StackOverflow /教程中找不到任何答案呢?
我能想到的唯一原因是访问令牌带有到期时间(在1小时到60天之间的任何时间);因此,也许我应该一直在重复使用相同的访问令牌,只要它是有效的(这将需要存储它,并将解释为什么Python Social Auth需要额外的表)。 Google / Facebook是否会因为太频繁地请求新的访问令牌而使我生气并阻止我?我在他们的文档中找不到任何提及。
编辑
这是Facebook代码,以防万一有人发现这些片段有用:
# views.py
def login_view(request):
return render(request, 'login.html', {
'facebook_url': 'https://www.facebook.com/v3.2/dialog/oauth?' + urllib.parse.urlencode({
'client_id': FACEBOOK_ID,
'redirect_uri': request.build_absolute_uri(reverse('oauth_facebook')),
'scope': 'email',
}),
}) # use this url in the template as a social login
def oauth_facebook(request):
code = request.GET['code']
response = requests.get('https://graph.facebook.com/v3.2/oauth/access_token', {
'code': code,
'client_id': FACEBOOK_ID,
'client_secret': FACEBOOK_SECRET,
'redirect_uri': request.build_absolute_uri(reverse('oauth_facebook')),
}).json()
access_token = response['access_token']
response = requests.get('https://graph.facebook.com/me', {
'access_token': access_token,
'fields': 'email',
}).json()
email = response['email']
user = User.objects.filter(username=email).first()
if not user:
user = User(username=email)
user.save()
auth.login(request, user)
return redirect('index')
# urls.py
urlpatterns = [
...
path('oauth/facebook', views.oauth_facebook, name='oauth_facebook'),
]