如何解决Flask登录中的谷歌登录问题?

问题描述 投票:0回答:1

我正试图将Google Signin与我的Flask应用集成。我正在使用Flask、Flask-Login和Flask-WTF。我有一个可以工作的应用程序,允许我正常登录、注册和注销。到目前为止,我可以启动Google SigninAuthorization过程,但一旦我选择我的Google账户,应用程序就会崩溃。

我试了很多方法才达到现在的效果,但现在我被卡住了。我认为我的问题是当谷歌试图将我的谷歌帐户与我的数据库连接时。然而,我不太确定从这里去哪里。

import os
os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
os.environ['OAUTHLIB_RELAX_TOKEN_SCOPE'] = '1'
from flask import Flask, render_template, redirect, url_for
from flask_bootstrap import Bootstrap
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField
from wtforms.validators import InputRequired, Email, Length
from flask_sqlalchemy  import SQLAlchemy
from werkzeug.security import generate_password_hash, check_password_hash
from flask_admin import Admin, AdminIndexView
from flask_admin.contrib.sqla import ModelView
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user
from flask_dance.contrib.google import make_google_blueprint, google
from flask_dance.consumer.storage.sqla import OAuthConsumerMixin, SQLAlchemyStorage
from flask_dance.consumer import oauth_authorized
from sqlalchemy.orm.exc import NoResultFound


app = Flask(__name__)

app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SECRET_KEY'] = 'Thisissupposedtobesecret!'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////sqlite3/login.db'
bootstrap = Bootstrap(app)
db = SQLAlchemy(app)


app.config["GOOGLE_OAUTH_CLIENT_ID"] = ("123")
app.config["GOOGLE_OAUTH_CLIENT_SECRET"] = ("123")
app.config["OAUTHLIB_RELAX_TOKEN_SCOPE"] = True
app.config["OAUTHLIB_INSECURE_TRANSPORT"] = True
google_bp = make_google_blueprint(scope=["https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email openid"])
app.register_blueprint(google_bp, url_prefix="/google_login")

login_manager = LoginManager(app)
login_manager.init_app(app)
login_manager.login_view = 'login'


class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(15), unique=True)
    email = db.Column(db.String(50), unique=True)
    password = db.Column(db.String(80))

    def __init__(self, username, email, password):
        self.username = username
        self.email = email
        self.password = password

    def is_authenticated(self):
        return True

    def is_active(self):
        return True

    def is_anonymous(self):
        return False

    def get_id(self):
        return str(self.id)

    def __repr__(self):
        return '<User %r>' %(self.username)


class OAuth(OAuthConsumerMixin, db.Model):
    user_id = db.Column(db.Integer, db.ForeignKey(User.id))
    user = db.relationship(User)


@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))


google_bp.storage = SQLAlchemyStorage(OAuth, db.session, user=current_user)


class MyModelView(ModelView):
    def is_accessible(self):
        return current_user.is_authenciated

    def inaccessible_callback(self, name, **kwargs):
        return redirect(url_for('login'))


class MyAdminIndexView(AdminIndexView):
    def is_accessible(self):
        return current_user.is_authenticated


admin = Admin(app, index_view=MyAdminIndexView())
admin.add_view(ModelView(User, db.session))
admin.add_view(ModelView(OAuth, db.session))


class LoginForm(FlaskForm):
    username = StringField('username', validators=[InputRequired(), Length(min=4, max=15)])
    password = PasswordField('password', validators=[InputRequired(), Length(min=8, max=80)])
    remember = BooleanField('remember me')


class RegisterForm(FlaskForm):
    email = StringField('email', validators=[InputRequired(), Email(message='Invalid email'), Length(max=50)])
    username = StringField('username', validators=[InputRequired(), Length(min=4, max=15)])
    password = PasswordField('password', validators=[InputRequired(), Length(min=8, max=80)])


@app.route('/')
def index():
    return render_template('index.html')


@app.route("/google")
def google_login():
    if not google.authorized:
        return redirect(url_for('google.login'))
    return redirect(url_for('dashboard'))


@oauth_authorized.connect_via (google_bp)
def google_is_logged_in(blueprint,token):
        account_info = blueprint.session.get('/oauth2/v3/userinfo')
        if account_info.ok:
            account_info_json = account_info.json()
            username = account_info_json['name']
            query = User.query.filter_by(username=form.username.data)
            try:
                user = query.first()
            except NoResultFound:
                user = User(username=form.username.data)
                db.session.add(user)
                db.session.commit()

            login_user(user)


@app.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()

    if form.validate_on_submit():
        user = User.query.filter_by(username=form.username.data).first()
        user.is_active = True

        if user:
            if check_password_hash(user.password, form.password.data):
                login_user(user, remember=form.remember.data)
                return redirect(url_for('dashboard'))

        if not user:
            user = User(username=form.username.data)
            db.session.add(user)
            db.session.commit()

        login_user(user)

        return '<h1>Invalid username or password</h1>'

        return '<h1>' + form.username.data + ' ' + form.password.data + '</h1>'
    return render_template('login.html', form=form)


@app.route('/signup', methods=['GET', 'POST'])
def signup():
    form = RegisterForm()

    if form.validate_on_submit():
        hashed_password = generate_password_hash(form.password.data, method='sha256')
        new_user = User(username=form.username.data, email=form.email.data, password=hashed_password)
        db.session.add(new_user)
        db.session.commit()
        return '<h1>New user has been created!</h1>'
        return '<h1>' + form.username.data + ' ' + form.email.data + ' ' + form.password.data + '</h1>'

    return render_template('signup.html', form=form)


@app.route('/dashboard')
@login_required
def dashboard():
    return render_template('dashboard.html', name=current_user.username)


@app.route('/logout')
@login_required
def logout():
    logout_user()
    return redirect(url_for('index'))


if __name__ == '__main__':
    app.run(debug=True)
'''

我可以正常登录、注销和注册。然而,当我尝试启动谷歌登录时,当我选择我的谷歌帐户时,应用程序立即崩溃。以下是我收到的错误信息。

127.0.0.1 - - [05/Aug/2019 20:53:56] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [05/Aug/2019 20:54:01] "GET /google HTTP/1.1" 302 -
127.0.0.1 - - [05/Aug/2019 20:54:01] "GET /google_login/google HTTP/1.1" 302 -
[2019-08-05 20:54:05,320] ERROR in app: Exception on /google_login/google/authorized [GET]
Traceback (most recent call last):
  File "D:\PyCharm Projects\Plutone\lib\site-packages\flask\app.py", line 2311, in wsgi_app
    response = self.full_dispatch_request()
  File "D:\PyCharm Projects\Plutone\lib\site-packages\flask\app.py", line 1834, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "D:\PyCharm Projects\Plutone\lib\site-packages\flask\app.py", line 1737, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "D:\PyCharm Projects\Plutone\lib\site-packages\flask\_compat.py", line 36, in reraise
    raise value
  File "D:\PyCharm Projects\Plutone\lib\site-packages\flask\app.py", line 1832, in full_dispatch_request
    rv = self.dispatch_request()
  File "D:\PyCharm Projects\Plutone\lib\site-packages\flask\app.py", line 1818, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "D:\PyCharm Projects\Plutone\lib\site-packages\flask_dance\consumer\oauth2.py", line 271, in authorized
    results = oauth_authorized.send(self, token=token) or []
  File "D:\PyCharm Projects\Plutone\lib\site-packages\blinker\base.py", line 267, in send
    for receiver in self.receivers_for(sender)]
  File "D:\PyCharm Projects\Plutone\lib\site-packages\blinker\base.py", line 267, in <listcomp>
    for receiver in self.receivers_for(sender)]
  File "D:\PyCharm Projects\Plutone\app.py", line 129, in google_is_logged_in
    query = User.query.filter_by(username=form.username.data)
NameError: name 'form' is not defined
127.0.0.1 - - [05/Aug/2019 20:54:05] "GET /google_login/google/authorized?state=U6S2e05D0wFNCcVSDNaZMgzYXIjrad&code=4%2FnQEU2cmc-ENix4_HvQP3t2jadQvXwFSGO2qw93w-Pr2ND_HnIAhDfVXWPGJBJHgFqlcoz6aIYid7o4_a1cJW1Zk&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+openid&authuser=0&session_state=8588e8ce3cddf3f4a89d8e65f56ce4a61b2fb901..f541&prompt=consent HTTP/1.1" 500 -
flask-wtforms flask-login
1个回答
0
投票

Traceback说你必须在你的函数google_is_logged_in(blueprint,token)里面定义'form',就像你在142行做的那样。

© www.soinside.com 2019 - 2024. All rights reserved.