У меня есть приложение Python, работающее на Ubuntu 16.04.На веб-интерфейсе у меня есть кнопка входа в Google, которая работает неправильно.Когда я нажимаю кнопку входа в Google, я могу выбрать свою учетную запись Google и ввести свой пароль.После этого он загружается, и я возвращаюсь на страницу входа без кнопки входа в Google.В консоли Chrome я вижу
```Failed to load resource: the server responded with a status of 500 (INTERNAL SERVER ERROR)```
http://18.196.81.95.nip.io/gconnect?state=C4NV826RSMFGKBU2XT9SP668Q0M0C461
При переходе по ссылке я получаю метод 405. Недопустимый метод.
Я добавил http://18.196.81.95.nip.io, http://18.196.81.95 и http://18.196.81.95.nip.io/gconnect на моей странице учетных данных Google Api в качестве разрешенного URL-адреса перенаправления.
здесь мой файл auth.py
```#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
from flask import Blueprint, flash, make_response, request, redirect
from flask import render_template, url_for
from flask import session as login_session
from oauth2client.client import flow_from_clientsecrets
from oauth2client.client import FlowExchangeError
import views.user as user
import httplib2
import json
import requests
import random
import string
auth = Blueprint('auth', __name__)
GOOGLE_CLIENT_SECRET = "/var/www/catalog/catalog/views/client_secret.json"
GOOGLE_CLIENT_ID = json.loads(
open(GOOGLE_CLIENT_SECRET, "r").read())["web"]["client_id"]
@auth.route("/login")
def show_login():
"""Create anti-forgery state token."""
state = "".join(random.choice(string.ascii_uppercase + string.digits)
for x in range(32))
login_session["state"] = state
return render_template("login.html", STATE=state)
@auth.route("/gconnect", methods=["POST"])
def gconnect():
"""Google connect."""
# Validate state token
if request.args.get("state") != login_session["state"]:
response = make_response(json.dumps("Invalid state parameter."), 401)
response.headers["Content-Type"] = "application/json"
return response
# Obtain authorization code
code = request.data
try:
# Upgrade the authorization code into a credentials object
oauth_flow = flow_from_clientsecrets(GOOGLE_CLIENT_SECRET, scope="")
oauth_flow.redirect_uri = "postmessage"
credentials = oauth_flow.step2_exchange(code)
except FlowExchangeError:
response = make_response(
json.dumps("Failed to upgrade the authorization code."), 401)
response.headers["Content-Type"] = "application/json"
return response
# Check that the access token is valid.
access_token = credentials.access_token
url = ("https://www.googleapis.com/oauth2/v1/tokeninfo?"
"access_token={}").format(access_token)
h = httplib2.Http()
result = json.loads(h.request(url, "GET")[1])
# If there was an error in the access token info, abort.
if result.get("error") is not None:
response = make_response(json.dumps(result.get("error")), 500)
response.headers["Content-Type"] = "application/json"
return response
# Verify that the access token is used for the intended user.
gplus_id = credentials.id_token["sub"]
if result["user_id"] != gplus_id:
response = make_response(
json.dumps("Token's user ID doesn't match given user ID."), 401)
response.headers["Content-Type"] = "application/json"
return response
# Verify that the access token is valid for this app.
if result["issued_to"] != GOOGLE_CLIENT_ID:
response = make_response(
json.dumps("Token's client ID does not match app's."), 401)
response.headers["Content-Type"] = "application/json"
return response
stored_access_token = login_session.get("access_token")
stored_gplus_id = login_session.get("gplus_id")
if stored_access_token is not None and gplus_id == stored_gplus_id:
response = make_response(
json.dumps("Current user is already connected."), 200)
response.headers["Content-Type"] = "application/json"
return response
# Store the access token in the session for later use.
login_session["access_token"] = credentials.access_token
login_session["gplus_id"] = gplus_id
# Get user info
userinfo_url = "https://www.googleapis.com/oauth2/v1/userinfo"
params = {"access_token": credentials.access_token, "alt": "json"}
answer = requests.get(userinfo_url, params=params)
data = answer.json()
login_session["username"] = data["name"]
login_session["picture"] = data["picture"]
login_session["email"] = data["email"]
# Add provider to login session.
login_session["provider"] = "google"
# See if user exists, if it doesn't make a new one.
user_id = user.get_user_id(data["email"])
if not user_id:
user_id = user.create_user(login_session)
login_session["user_id"] = user_id
output = "<h1>Welcome, "
output += login_session["username"]
output += "!</h1>"
output += '<img src="' + login_session["picture"] + '" '
output += 'style = "width: 300px; height: 300px; border-radius: 150px; '
output += '-webkit-border-radius: 150px; -moz-border-radius: 150px;"> '
flash(
"You are now logged in as {}.".format(login_session["username"]),
"success")
return output
@auth.route("/gdisconnect")
def gdisconnect():
"""Google disconnect."""
# Revoke a current user's token and reset their login_session.
# Only disconnect a connected user.
access_token = login_session.get("access_token")
if access_token is None:
response = make_response(
json.dumps("Current user not connected."), 401)
response.headers["Content-Type"] = "application/json"
return response
url = "https://accounts.google.com/o/oauth2/revoke?token={}".format(
access_token)
h = httplib2.Http()
result = h.request(url, "GET")[0]
if result["status"] == "200":
del login_session["access_token"]
del login_session["gplus_id"]
del login_session["username"]
del login_session["email"]
del login_session["picture"]
response = make_response(json.dumps("Successfully disconnected."), 200)
response.headers["Content-Type"] = "application/json"
return response
else:
response = make_response(
json.dumps("Failed to revoke token for given user.", 400))
response.headers["Content-Type"] = "application/json"
return response```
и часть моего файла login.html какхорошо
```<html>
<head>
<!--LOAD PRE-REQUISITES FOR GOOGLE SIGN IN -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://apis.google.com/js/client:platform.js?onload=start" async defer></script>
<script>
function start() {
gapi.load('auth2', function() {
auth2 = gapi.auth2.init({
client_id: '325785460740-0ik2v5alkanj3unor80catc05l2qnqc8.apps.googleusercontent.com'
});
});
}
</script
<!-- END PRE-REQUISITES FOR GOOGLE SIGN IN -->
<!-- Bootstrap CSS -->
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css"
integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M"
crossorigin="anonymous">
<style>
body { margin: 10px; }
</style>
</head>
<body>
<!-- GOOGLE PLUS SIGN IN -->
<button id="signinButton">Google Signin</button>
<div id="result"></div>
<script>
$('#signinButton').click(function() {
function signInCallback(authResult){
if (authResult['code']){
$('#signinButton').attr('style', 'display: none');
$.ajax({
type: 'POST',
url: '/gconnect?state={{STATE}}',
headers: {
'X-Requested-With': 'XMLHttpRequest'
},
contentType: 'application/octet-stream; charset=utf-8',
success:function(result){
$('#result').html('Login Successful!</br>'+ result + '</br>Redirecting...')
setTimeout(function() {
window.location.href = "/catalog";
}, 2000);
},
processData:false,
data:authResult['code']
});
} else{
// handle error
console.log('There was an error: ' + authResult['error']);
$('#result').html('Failed to make a server-side call. Check your configuration and console.');
}
}
auth2.grantOfflineAccess().then(signInCallback);
});
</script>
<!--END GOOGLE PLUS SIGN IN -->`
``
Я знаю, что это много кода, надеюсь, кто-нибудь еще может помочь мне исправить это.
Я просмотрел документацию Google oauth, но не смог найти ничего плохого в своем коде.