2013-07-20 2 views
1

내 Django 사이트에서 Github을 통해 인증을 시도하고 있습니다. 나는 두 가지 질문이Github OAuth 인증 정보

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') 

:

  1. 는이 안전을 안전하고 이런 식으로 일이 내가 생각 해낸 무엇인가?
  2. 세션에 만료 시간을 설정해야합니까? 왜냐하면 지금은 결코 만료되지 않을 것 같아서요.

참고 : 나는 또한 rauth 사용하고 있습니다 : 그것은있을 수 https://rauth.readthedocs.org/en/latest/

답변

1

같은 보안되지 않음으로하고 몇 가지 세부 사항이 부족하다. 훨씬 더 안전한 상태 값을 사용 SystemRandom에 대한

    • .
    • 세션이 cookie based입니까? 그들은 기본적으로되지 않을 것이며 그렇게해서는 안됩니다.
    • 리디렉션은 HTTPS로 다시 보호됩니까?
    • HTTPS를 통한 GitHub에 대한 귀하의 모든 요청은 있습니까? 토큰을 얻은 후에도?
  1. 기본 만료 기간은 2 주이지만 OAuth 2 액세스 토큰은 일반적으로 훨씬 빨리 만료됩니다. 그러나 GitHub 토큰이 만료되지 않기 때문에 세션이 끝나면 세션이 만료되고 더 이상 필요하지 않을 때 delete the token이 만료 될 것입니다.

내가 강력하게 해당 프로젝트가에 더 많은 눈이 잠시 동안 있었다으로 자신의 GitHub의 로그인 롤링 대신 python-social-auth를 사용하는 것이 좋습니다 것이라고 말했다.

+0

답변 해 주셔서 감사합니다. 그래서 세션은 쿠키를 기반으로하지 않습니다 (나는 그들이해야합니까?). 내 사이트는 HTTPS가 아니지만 Github에 대한 모든 요청은 HTTPS에 있습니다. 전에 django-social-auth를 사용하고 있었지만 문제가 발생하여 내 솔루션을 롤업하기로했습니다 (Github 로그인 만 필요함). 아마 다시 시도 할게. – rubik

+0

쿠키 기반이 아니어야하며 답변을 편집 할 수 있습니다. 또한 사이트가 https에 있지 않은 경우 인증 코드는 스니핑되어 클라이언트 보안을 도용하거나 추측 할 수있는 경우 액세스 토큰을 얻는 데 사용될 수 있습니다. –

+0

물론 HTTPS를 사용하지 않으면 다른 많은 공격이 가능하므로 OAuth 2를 사용하려면 HTTPS를 사용하십시오. –