我尝试使用烧瓶登录构建谷歌登录。我在这里找到了主题 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.py
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')
我在 main.py 中构建的用户视图页面
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 = oauth.callback()
print("da lay duoc email", email)
什么都没来!所以任何人都可以帮助我 谢谢大家