我正在尝试通过 Django 网站上的 Github 进行身份验证。这就是我想到的:
import string
import random
import urllib
from django.conf import settings
from django.core.urlresolvers import reverse
from django.shortcuts import redirect
from django.utils.crypto import constant_time_compare
from django.contrib.auth import login
from rauth import OAuth2Service
from mongoengine.django.auth import User
from utils import make_absolute
SESSION_KEY = '_oauth_access_token'
SESSION_STATE = '_oauth_state'
github = OAuth2Service(
client_id=settings.GITHUB_APP_ID,
client_secret=settings.GITHUB_API_SECRET,
name='github',
authorize_url='https://github.com/login/oauth/authorize',
access_token_url='https://github.com/login/oauth/access_token',
base_url='http://github.com/')
def random_string():
return ''.join(random.choice(string.ascii_letters + string.digits)
for _ in xrange(random.randint(27, 49)))
def flush_and_set(request, key, value):
if key in request.session:
if request.session[key] != value:
request.session.flush()
else:
request.session.cycle_key()
request.session[key] = value
def start_pipeline(request):
state = random_string()
flush_and_set(request, SESSION_STATE, state)
return redirect(github.get_authorize_url(
redirect_uri=make_absolute(reverse('auth-pipeline-end')),
state=state))
def end_pipeline(request):
if not constant_time_compare(request.session[SESSION_STATE],
request.GET['state']):
return redirect('home')
session = github.get_auth_session(data={'code': request.GET['code'],
'redirect_uri':
make_absolute(reverse('home'))})
flush_and_set(request, SESSION_KEY, session.access_token)
user_data = session.get('https://api.github.com/user?' +
urllib.urlencode({'access_token':
session.access_token})).json()
username = user_data['login']
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
user = User(username=username)
for field in ('email',):
d = user_data[field]
if d:
setattr(user, field, d)
user.backend = 'mongoengine.django.auth.MongoEngineBackend'
user.save()
login(request, user)
return redirect('home')
我有两个问题:
- 这样做安全可靠吗?
- 我应该设置 session 到期时间吗?因为现在在我看来它永远不会过期。
注意:我也在使用 rauth:https://rauth.readthedocs.org/en/latest/
最佳答案
不够安全,并且缺少一些细节。
- 要获得更安全的状态值,请使用 SystemRandom .
- 您的 session 是 cookie based ?它们不会是默认的,也不应该是默认的。
- 重定向回来是否受 HTTPS 保护?
- 您对 GitHub 的所有请求都是通过 HTTPS 发送的吗?也获得token之后?
默认过期时间为 2 周,但 OAuth 2 访问 token 通常过期得更快。不过,我相信 GitHub token 永远不会过期,因此改进是在关闭时使 session 过期,并且 delete the token当不再需要时。
也就是说,我强烈鼓励您使用 python-social-auth而不是滚动你自己的 GitHub 登录,因为该项目已经有很多人关注它并且已经关注了一段时间了。
关于python - 关于 Github OAuth 身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17759513/