2012-04-22 45 views
15

Tôi đã tìm kiếm 2 ngày để có câu trả lời nhưng không có gì xuất hiện.Python Oauth2 - đăng nhập bằng Google

Tôi đang cố gắng tích hợp Oauth2 để đăng nhập bằng Google trên Django. Mã tôi đã ném một ngoại lệ - "Mã thông báo không hợp lệ".

Điều này xảy ra:

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

trong google_authenticate()

Xin vui lòng, giúp tôi.

Mã của tôi:

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

Trả lời

23

Sau một thời gian dài, và nhiều giờ làm việc ra đi để lãng phí, tôi đã từ bỏ với OAuth2 vì nó là khó khăn để cấu hình, và tất cả tôi cần là để đăng nhập người dùng trong. Các mã sau đây sẽ giúp một người cần phải làm một cái gì đó tương tự, và có thể được tùy chỉnh. Tất cả những gì tôi làm là làm theo hướng dẫn về việc tạo các url và như vậy ở đây ->https://developers.google.com/accounts/docs/OAuth2Login

Tôi đã thực hiện hai chế độ xem (cho bất kỳ ai không sử dụng Django - trang) và tạo liên kết đến trang đầu tiên: Trang này tôi gọi là đăng nhập/google và tạo liên kết đến nó từ trang đăng nhập.

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) 

Mã trên được chuyển hướng đến trang thứ hai (trang này phải được định nghĩa là uri chuyển hướng trong định nghĩa ứng dụng google). tôi gọi này trang đăng nhập/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') 

Tôi thực sự hy vọng điều này sẽ giúp mọi người ra khỏi đó, và tiết kiệm cho họ những giờ tôi lãng phí. Nhận xét về mã được chào đón nhiều hơn!

+7

Nếu có ai đó thắc mắc, bây giờ có thư viện oauth2client từ Google triển khai luồng và lưu trữ cho thông tin đăng nhập => bây giờ phải mất 10 dòng trong tất cả https://developers.google.com/api-client-library/python/ hướng dẫn/aaa_oauth http://code.google.com/p/google-api-python-client/source/browse/#hg%2Fsamples%2Fdjango_sample – lajarre

+1

@ user1160475 hãy xem developers.google.com. Bạn đã có tên người dùng và mật khẩu google, hãy đăng nhập. – Meir

+0

Cảm ơn bạn. Mã hoạt động. Đã cho tôi một thời gian để tìm ra rằng Http() lớp được định nghĩa trong httplib2. –

Các vấn đề liên quan