Python Oauth2 - логин в Google
Я искал ответ на 2 дня, но ничего не получилось.
Я пытаюсь интегрировать Oauth2 для входа в Google на Django. Код, который у меня есть, вызывает исключение - "Недопустимый токен".
Это происходит:
resp, content = client.request(access_token_url, "POST")
if resp['status'] != '200':
print content
raise Exception("Invalid response from Google."+content)
в google_authenticate()
Пожалуйста, помогите мне.
Мой код:
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 pre-built
# functions for these things.
user = authenticate(username=access_token['screen_name'],
password=access_token['oauth_token_secret'])
login(request, user)
return HttpResponseRedirect('/')
Ответы
Ответ 1
После долгого времени и много часов, потраченных впустую, я отказался от OAuth2, поскольку его сложно настроить, и все, что мне нужно, - это войти в систему пользователя. Следующий код должен помочь кому-то, кто должен что-то сделать подобный, и может быть настроен. Все, что я сделал, это следовать инструкциям по формированию URL-адресов и тому подобное → https://developers.google.com/accounts/docs/OAuth2Login
Я сделал два представления (для тех, кто не использует Django-страницы) и сделал ссылку на первую:
На этой странице я назвал login/google и сделал ссылку на нее со страницы входа.
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)
Приведенный выше код перенаправляется на вторую страницу (эта страница должна быть определена как URL-адрес перенаправления в определениях приложений Google).
Я назвал эту страницу login/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')
Я действительно надеюсь, что это поможет людям там, и сэкономит им часы, которые я потратил впустую. Комментарии к коду более чем приветствуются!