问题描述
我尝试使用flask登录构建gooogle登录。 我在这里找到线程 Using Google OAuth2 with Flask
我能够移植接受的答案以使用requests-oauthlib而不是Rauth。在撰写本文时,该软件包的最后一次提交是在2019年6月,当前已被30K +存储库使用。
初始 .py
from flask import Flask
from flask_sqlalchemy import sqlAlchemy
from flask_login import LoginManager
import dir
from flask_mail import Mail
# init sqlAlchemy so we can use it later in our models
db = sqlAlchemy()
mail = Mail()
GOOGLE_LOGIN_CLIENT_ID = "myGoogle Api id .apps.googleusercontent.com" #I am sure It is correct
GOOGLE_LOGIN_CLIENT_SECRET = "my_secret_key"
def create_app():
app = Flask(__name__)
app.debug = True
app.config['SECRET_KEY'] = 'secret-key-goes-here'
# app.config['sqlALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite'
app.config['sqlALCHEMY_DATABASE_URI'] = 'sqlite:////' + str(dir.dir) + '/admin.sqlite'
app.config['MAIL_SERVER'] = 'smtp.gmail.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USERNAME'] = 'ruaxe.sdafsafsafs'
app.config['MAIL_PASSWORD'] = 'uiykejafsaffiqklziccld'
app.config['MAIL_USE_TLS'] = False
app.config['MAIL_USE_SSL'] = True
app.config['OAUTH_CREDENTIALS'] = {
'google': {
'id': GOOGLE_LOGIN_CLIENT_ID,'secret': GOOGLE_LOGIN_CLIENT_SECRET
}
}
mail.init_app(app)
db.init_app(app)
with app.app_context():
db.create_all()
login_manager = LoginManager()
login_manager.login_view = 'auth.login'
login_manager.init_app(app)
from .models import User
@login_manager.user_loader
def load_user(user_id):
# since the user_id is just the primary key of our user table,use it in the query for the user
return User.query.get(int(user_id))
# blueprint for auth routes in our app
from .auth import auth as auth_blueprint
app.register_blueprint(auth_blueprint)
# blueprint for non-auth parts of app
from .main import main as main_blueprint
app.register_blueprint(main_blueprint)
return app
auth = Blueprint('auth',__name__)
@auth.route('/login',methods=['GET'])
def login():
if current_user is not None and current_user.is_authenticated:
return redirect(url_for('main.index'))
return render_template('login.html')
from __future__ import print_function
from flask import Blueprint,render_template,request,redirect,flash,url_for,current_app
from flask_login import login_required,current_user,login_user
from project.function import cmsHaravan as hara,cmsCalendar as cal
from .function import config as cf,cmsContacts as ct
from datetime import datetime,timedelta,date
from .models import User,Order,Shop
from . import db,mail
from flask_mail import Message
import random
import string
from werkzeug.security import generate_password_hash
import json
from requests_oauthlib import OAuth2Session
from urllib.request import urlopen
main = Blueprint('main',__name__)
class OAuthSignIn(object):
providers = None
def __init__(self,provider_name):
self.provider_name = provider_name
credentials = current_app.config['OAUTH_CREDENTIALS'][provider_name]
self.consumer_id = credentials['id']
self.consumer_secret = credentials['secret']
def authorize(self):
pass
def callback(self):
pass
def get_callback_url(self):
return url_for('main.profile',provider=self.provider_name,_external=True)
@classmethod
def get_provider(self,provider_name):
if self.providers is None:
self.providers={}
for provider_class in self.__subclasses__():
provider = provider_class()
self.providers[provider.provider_name] = provider
return self.providers[provider_name]
class GoogleSignIn(OAuthSignIn):
openid_url = "https://accounts.google.com/.well-kNown/openid-configuration"
def __init__(self):
super(GoogleSignIn,self).__init__("google")
self.openid_config = json.load(urlopen(self.openid_url))
self.session = OAuth2Session(
client_id=self.consumer_id,redirect_uri=self.get_callback_url(),scope=self.openid_config["scopes_supported"]
)
def authorize(self):
auth_url,_ = self.session.authorization_url(
self.openid_config["authorization_endpoint"])
print(auth_url)
return redirect(auth_url)
def callback(self):
if "code" not in request.args:
return None,None
self.session.fetch_token(
token_url=self.openid_config["token_endpoint"],code=request.args["code"],client_secret=self.consumer_secret,)
me = self.session.get(self.openid_config["userinfo_endpoint"]).json()
print(me)
print(me["name"],me["email"])
return me["name"],me["email"]
@main.route('/authorize/<provider>')
def oauth_authorize(provider):
# Flask-Login function
if not current_user.is_anonymous:
return redirect(url_for('index'))
oauth = OAuthSignIn.get_provider(provider)
return oauth.authorize()
@main.route('/profile/<provider>')
def oauth_callback(provider):
if not current_user.is_anonymous:
return redirect(url_for('main.index'))
oauth = OAuthSignIn.get_provider(provider)
name,email = oauth.callback()
print("da lay duoc email",email)
if email is None:
# I need a valid email address for my user identification
flash('Authentication Failed.')
return redirect(url_for('auth.login'))
# Look if the user already exists
user=User.query.filter_by(email=email).first()
if not user:
# Create the user. Try and use their name returned by Google,# but if it is not set,split the email address at the @.
name = name
if name is None or name == "":
name = email.split('@')[0]
# We can do more work here to ensure a unique nickname,if you
# require that.
user=User(firstname=name,email=email)
db.session.add(user)
db.session.commit()
# Log in the user,by default remembering them for their next visit
# unless they log out.
login_user(user,remember=True)
return redirect(url_for('main.index'))
@main.route('/profile')
@login_required
def profile():
ListCarBrands = cal.getListCarBrands()
ListProvinces = cal.getListProvinces()
order_email = current_user.email
list_order = {}
i = 0
for row in Order.query.filter_by(order_email=order_email):
i = i + 1
total_order = i
list_order[i] = row.__dict__
return render_template('profile.html',list_order=list_order,name=current_user.lastname,biensoxe=current_user.biensoxe,ListCarBrands=ListCarBrands,brands=current_user.brands,carclass=current_user.carclass,firstname=current_user.firstname,lastname=current_user.lastname,phone=current_user.phone,email=current_user.email,ListProvinces=ListProvinces,provinces=current_user.provinces)
login.html
{% extends "base.html" %}
{% block content %}
<div id="sign-in">
<h1>Sign In</h1>
<p>
<a href={{ url_for('main.oauth_authorize',provider='google') }}><img src="{{ url_for('static',filename='img/sign-in-with-google.png') }}" /></a>
</div>
<form method="POST" action="/login">
<div class="ui-information-body">
<div class="align-content-center">
{% with messages = get_flashed_messages() %}
{% if messages %}
<div class="notification is-danger">
{{ messages[0] }}
</div>
{% endif %}
{% endwith %}
<h4>Login {{ error }}</h4>
<div class="row">
<div class="col-5 "><label class="label-input-group">Email </label><input type="email"
class="next-input"
name="email" id="email"
value=""></div>
</div>
<div class="row">
<div class="col-5 "><label class="label-input-group">Password</label><input type="password"
class="next-input"
name="password"
id="password"
value=""></div>
</div>
<div class="row">
<div class="col-5 "><span class="label-input-group"><br></span>
<a href="{{ url_for('main.reset_password') }}" class="btn btn-danger btn-lg btn-block">
Nếu bạn quên mật khẩu? Reset
</a></div>
</div>
<div class="row">
<div class="col-5 "><span class="label-input-group"><br></span><input
class="btn btn-primary btn-lg btn-block" type="submit" value="Login"></div>
</div>
</div>
</div>
</div>
</form>
{% endblock %}
个人资料html
{% extends "base.html" %}
{% block content %}
<form method="POST" action="/profile">
Some code here for user can update profile
</form>
</div>
{% endblock %}
def authorize(self):
auth_url,_ = self.session.authorization_url(
self.openid_config["authorization_endpoint"])
print(auth_url) ##### This function run
return redirect(auth_url)
https://accounts.google.com/o/oauth2/v2/auth?response_type=code&client_id=880298757050-ij79mostsm1fccdcvuj43m0oe0quisih.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A8000%2Fprofile%3Fprovider%3Dgoogle&scope=openid+email+profile&state=xwbrUEpMjhIFrM6l3PlXgcXdgzyDbd
127.0.0.1 - - [21/Aug/2020 14:03:32] "GET /authorize/google HTTP/1.1" 302 -
127.0.0.1 - - [21/Aug/2020 14:03:35] "GET /profile?provider=google&state=xwbrUEpMjhIFrM6l3PlXgcXdgzyDbd&code=4%2F3QFTG6I2FzBPUKD_Sk0hq4IUhlr0jA4EQ2fTLyQizyYsPkCLxRf_WXwQz929v4wUeJhN4IXWFWu7nLKBJ2NHhog&scope=email+profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&authuser=0&prompt=consent HTTP/1.1" 302 -
127.0.0.1 - - [21/Aug/2020 14:03:35] "GET /login?next=%2Fprofile%3Fprovider%3Dgoogle%26state%3DxwbrUEpMjhIFrM6l3PlXgcXdgzyDbd%26code%3D4%252F3QFTG6I2FzBPUKD_Sk0hq4IUhlr0jA4EQ2fTLyQizyYsPkCLxRf_WXwQz929v4wUeJhN4IXWFWu7nLKBJ2NHhog%26scope%3Demail%2Bprofile%2Bopenid%2Bhttps%253A%252F%252Fwww.googleapis.com%252Fauth%252Fuserinfo.email%2Bhttps%253A%252F%252Fwww.googleapis.com%252Fauth%252Fuserinfo.profile%26authuser%3D0%26prompt%3Dconsent HTTP/1.1" 200 -
127.0.0.1 - - [21/Aug/2020 14:03:35] "GET /static/img/sign-in-with-google.png HTTP/1.1" 404 -
127.0.0.1 - - [21/Aug/2020 14:03:35] "GET /static/css/bootstrap.js HTTP/1.1" 404 -
oauth = OAuthSignIn.get_provider(provider)
name,email)
一无所有!所以任何人都可以帮助我 感谢所有人
解决方法
谢谢大家 我更改范围并运行!
class GoogleSignIn(OAuthSignIn):
openid_url = "https://accounts.google.com/.well-known/openid-configuration"
def __init__(self):
super(GoogleSignIn,self).__init__("google")
self.openid_config = json.load(urlopen(self.openid_url))
self.session = OAuth2Session(
client_id=self.consumer_id,redirect_uri=self.get_callback_url(),scope='https://www.googleapis.com/auth/userinfo.profile openid https://www.googleapis.com/auth/userinfo.email'
)