2012-04-22 13 views
15

Szukałem odpowiedzi przez 2 dni, ale nic nie znalazłem.Python Oauth2 - zaloguj się za pomocą Google

Próbuję zintegrować Oauth2 do logowania z Google na Django. Kod, który zgłasza wyjątek - "Token jest nieważny".

Dzieje:

resp, content = client.request(access_token_url, "POST") 
    if resp['status'] != '200': 
     print content 
     raise Exception("Invalid response from Google."+content) 

w google_authenticate()

Proszę, pomóż mi.

Mój kod:

def google_login(request): 
    scope = "https://www.googleapis.com/auth/userinfo.profile" 

    request_token_url = "https://www.google.com/accounts/OAuthGetRequestToken?scope=%s" % scope 
    authorize_url = 'https://www.google.com/accounts/OAuthAuthorizeToken' 
    authenticate_url = "https://accounts.google.com/o/oauth2/auth" 

    response_type = "code" 
    redirect_uri = "http://127.0.0.1:8000/login/google/auth" 
    scope = "https://www.googleapis.com/auth/userinfo.profile" 

    oauth_key = settings.GOOGLE_KEY 
    oauth_secret = settings.GOOGLE_SECRET 

    consumer = oauth.Consumer(oauth_key, oauth_secret) 
    client = oauth.Client(consumer) 

    # Step 1: Get a request token. This is a temporary token that is used for 
    # having the user authorize an access token and to sign the request to obtain 
    # said access token. 

    resp, content = client.request(request_token_url, "POST") 
    request_token = dict(urlparse.parse_qsl(content)) 

    if resp['status'] != '200': 
     raise Exception("Invalid response from Google.") 

    # Step 2. Store the request token in a session for later use. 
    request.session['request_token'] = dict(cgi.parse_qsl(content)) 

    # Step 3. Redirect the user to the authentication URL. 
    url = "%s?oauth_token=%s&client_id=%s&response_type=%s&redirect_uri=%s&scope=%s" % (authenticate_url, 
     request.session['request_token']['oauth_token'], 
     oauth_key,response_type,redirect_uri,scope) 

    return HttpResponseRedirect(url) 

def google_authenticate(request): 
    access_token_url = 'https://www.google.com/accounts/OAuthGetAccessToken' 

    oauth_key = settings.GOOGLE_KEY 
    oauth_secret = settings.GOOGLE_SECRET 

    consumer = oauth.Consumer(oauth_key, oauth_secret) 

    # Step 1. Use the request token in the session to build a new client. 
    token = oauth.Token(request.session['request_token']['oauth_token'], 
     request.session['request_token']['oauth_token_secret']) 
    if 'oauth_verifier' in request.GET: 
     token.set_verifier(request.GET['oauth_verifier']) 
    client = oauth.Client(consumer, token) 

    # Step 2. Request the authorized access token from Google. 
    resp, content = client.request(access_token_url, "POST") 
    if resp['status'] != '200': 
     print content 
     raise Exception("Invalid response from Google."+content) 

    access_token = dict(cgi.parse_qsl(content)) 

    # Step 3. Lookup the user or create them if they don't exist. 
    try: 
     user = User.objects.get(username=access_token['screen_name']) 
    except User.DoesNotExist: 
     # When creating the user I just use their [email protected] 
     # for their email and the oauth_token_secret for their password. 
     # These two things will likely never be used. Alternatively, you 
     # can prompt them for their email here. Either way, the password 
     # should never be used. 
     user = User.objects.create_user(access_token['screen_name'], 
      '%[email protected]' % access_token['screen_name'], 
      access_token['oauth_token_secret']) 

     # Save our permanent token and secret for later. 
     profile = Profile() 
     profile.user = user 
     profile.oauth_token = access_token['oauth_token'] 
     profile.oauth_secret = access_token['oauth_token_secret'] 
     profile.save() 

    # Authenticate the user and log them in using Django's pre-built 
    # functions for these things. 
    user = authenticate(username=access_token['screen_name'], 
     password=access_token['oauth_token_secret']) 
    login(request, user) 

    return HttpResponseRedirect('/') 

Odpowiedz

23

Po długim czasie i wielu godzin spędzonych poszedł na marne, zrezygnowałem z OAuth2 ponieważ trudno jest skonfigurować, a wszystko, co potrzebne jest do zalogowania użytkownika w. Poniższy kod powinien pomóc komuś, kto potrzebuje czegoś podobnego, i może być dostosowany. Wszystko co zrobiłem to postępować zgodnie z instrukcjami tworzenia adresów URL i tutaj ->https://developers.google.com/accounts/docs/OAuth2Login

Zrobiłem dwa widoki (dla każdego, kto nie używa Django - strony) i zrobiłem link do pierwszego: Ta strona nazwałem login/google i zrobił link do niego ze strony logowania.

def google_login(request): 
    token_request_uri = "https://accounts.google.com/o/oauth2/auth" 
    response_type = "code" 
    client_id = XXXXXX-your_client_id 
    redirect_uri = "http://mysite/login/google/auth" 
    scope = "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email" 
    url = "{token_request_uri}?response_type={response_type}&client_id={client_id}&redirect_uri={redirect_uri}&scope={scope}".format(
     token_request_uri = token_request_uri, 
     response_type = response_type, 
     client_id = client_id, 
     redirect_uri = redirect_uri, 
     scope = scope) 
    return HttpResponseRedirect(url) 

Powyższy kod skierowane do drugiej strony (to strony muszą być zdefiniowane jako URI przekierowania w definicjach aplikacji google). nazwałem tę stronę logowania/Google/auth:

def google_authenticate(request): 
    parser = Http() 
    login_failed_url = '/' 
    if 'error' in request.GET or 'code' not in request.GET: 
     return HttpResponseRedirect('{loginfailed}'.format(loginfailed = login_failed_url)) 

    access_token_uri = 'https://accounts.google.com/o/oauth2/token' 
    redirect_uri = "http://mysite/login/google/auth" 
    params = urllib.urlencode({ 
     'code':request.GET['code'], 
     'redirect_uri':redirect_uri, 
     'client_id':XXXXX_your_google_key, 
     'client_secret':XXXXX_your_google_secret, 
     'grant_type':'authorization_code' 
    }) 
    headers={'content-type':'application/x-www-form-urlencoded'} 
    resp, content = parser.request(access_token_uri, method = 'POST', body = params, headers = headers) 
    token_data = jsonDecode(content) 
    resp, content = parser.request("https://www.googleapis.com/oauth2/v1/userinfo?access_token={accessToken}".format(accessToken=token_data['access_token'])) 
    #this gets the google profile!! 
    google_profile = jsonDecode(content) 
    #log the user in--> 
    #HERE YOU LOG THE USER IN, OR ANYTHING ELSE YOU WANT 
    #THEN REDIRECT TO PROTECTED PAGE 
    return HttpResponseRedirect('/dashboard') 

Naprawdę mam nadzieję, że to pomaga ludziom tam, i ratuje im godzin zmarnowałem. Komentarze do kodu są mile widziane!

+7

Jeśli ktoś się zastanawia, teraz jest biblioteka oauth2client z Google implementująca przepływy i pamięć dla poświadczeń => zajmuje teraz 10 wierszy w całości https://developers.google.com/api-client-library/python/ guide/aaa_oauth http://code.google.com/p/google-api-python-client/source/browse/#hg%2Fsamples%2Fdjango_sample – lajarre

+1

@ user1160475 zajrzyj na developers.google.com. Powinieneś już mieć nazwę użytkownika i hasło Google, być zalogowany. – Meir

+0

Dziękuję. Kod działa. Zajęło mi trochę czasu, aby dowiedzieć się, że klasa Http() jest zdefiniowana w httplib2. –

Powiązane problemy