I am trying to add login using google. I am using Oauth to achieve the same.
I am being re directed to the google login in page but upon logging in the during the call back I am constantly running into this error("Internal Server Error: The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.") & ("Invalid Client Error" in valid_token_paramerters unauthorized in the terminal) and after going through tons of articles I still unable to get through.
I am relatively new to this so I am unable to check as to where its going wrong.
Disclosure: I am using Flask for this app. GOOGLE_CLIENT_ID & GOOGLE_CLIENT_SECRET are assigned environment variables.
Here are the files: app.py
# Python standard libraries
import json
import os
import sqlite3
# Third-party libraries
from flask import Flask, redirect, request, url_for
from flask_login import (
LoginManager,
current_user,
login_required,
login_user,
logout_user,
)
from oauthlib.oauth2 import WebApplicationClient
import requests
# Internal imports
from db import init_db_command
from user import User
# Configuration
GOOGLE_CLIENT_ID = os.environ.get("GOOGLE_CLIENT_ID", None)
GOOGLE_CLIENT_SECRET = os.environ.get("GOOGLE_CLIENT_SECRET", None)
GOOGLE_DISCOVERY_URL = (
"https://accounts.google.com/.well-known/openid-configuration"
)
# Flask app setup
app = Flask(__name__)
app.secret_key = os.environ.get("SECRET_KEY") or os.urandom(24)
# User session management setup
# https://flask-login.readthedocs.io/en/latest
login_manager = LoginManager()
login_manager.init_app(app)
# Naive database setup
try:
init_db_command()
except sqlite3.OperationalError:
# Assuming it's already been created
pass
# OAuth 2 client setup
client = WebApplicationClient(GOOGLE_CLIENT_ID)
# Flask-Login helper to retrieve a user from our db
@login_manager.user_loader
def load_user(user_id):
return User.get(user_id)
@app.route("/")
def index():
if current_user.is_authenticated:
return (
"<p>Hello, {}! You're logged in! Email: {}</p>"
"<div><p>Google Profile Picture:</p>"
'<img src="{}" alt="Google profile pic"></img></div>'
'<a class="button" href="/logout">Logout</a>'.format(
current_user.name, current_user.email, current_user.profile_pic
)
)
else:
return '<a class="button" href="/login">Google Login</a>'
def get_google_provider_cfg():
return requests.get(GOOGLE_DISCOVERY_URL).json()
@app.route("/login")
def login():
#What URL to hit for google login
google_provider_cfg = get_google_provider_cfg()
authorization_endpoint = google_provider_cfg["authorization_endpoint"]
request_uri = client.prepare_request_uri(
authorization_endpoint,
redirect_uri=request.base_url + '/callback',
scope=["openid","email","profile"]
)
return redirect(request_uri)
@app.route("/login/callback")
def callback():
# Get the unique authorization code Google sent back to client
code = request.args.get("code")
# Finding the URL to hit to get tokens that will allow the app to ask for details on behalf of user
google_provider_cfg = get_google_provider_cfg()
token_endpoint = google_provider_cfg["token_endpoint"]
# Preparing token request
token_url, headers, body = client.prepare_token_request(
token_endpoint,
authorization_response=request.url,
code=code
)
token_response = requests.post(
token_url,
headers=headers,
data=body,
auth=(GOOGLE_CLIENT_ID,GOOGLE_CLIENT_SECRET)
)
# Pasing the tokens
client.parse_request_body_response(json.dumps(token_response.json()))
# After getting tokens, hititng the URL from google that gives us the User info
userinfo_endpoint = google_provider_cfg["userinfo_endpoint"]
uri, headers, body = client.add_token(userinfo_endpoint)
userinfo_response = requests.get(uri,headers=headers,data = body)
# Getting user info if the user's email is verified
if userinfo_response.json().get("email_verified"):
unique_id = userinfo_response.json()["sub"]
users_email = userinfo_response.json()["email"]
picture = userinfo_response.json()["picture"]
users_name = userinfo_response.json()["given_name"]
else:
return "User email is not available or verified by Google.", 400
# Creating user in Db with info from Google
user = User(
id_=unique_id,name=users_name,email=users_email,profile_pic=picture
)
# Adding user to database if user doesnt exist
if not User.get(unique_id):
User.create(unique_id,users_name,users_email,picture)
# Begin user session by loggin in
login_user(user)
# Sending it back to Home after authnetication
return redirect(url_for("index"))
@app.route("/logout")
@login_required
def logout():
logout_user()
return redirect(url_for("index"))
if __name__ == "__main__":
app.run(ssl_context="adhoc")
requirements.txt
requests==2.21.0
Flask==1.0.2
oauthlib==3.0.1
pyOpenSSL==19.0.0
Flask-Login==0.4.1
launch.json
{
"name": "Python: Flask",
"type": "python",
"request": "launch",
"module": "flask",
"env": {
"FLASK_APP": "application.py",
"FLASK_ENV": "development",
"FLASK_DEBUG": "0"
},
"args": [
"run",
"--no-debugger",
"--no-reload"
],
"jinja": true
}
Thanks in advance.
Aucun commentaire:
Enregistrer un commentaire