简体   繁体   中英

Flask-Login - User always not authenticated

I have been messing around and creating a user-authentication system. I tackled a bunch of bugs (thanks to Stackoverflow), however, I have run in to a bug that I cannot identify. When I login and it redirects me to my profile page, it brings me back to my login. Which is certainly expected if I try and access the page without proper credentials, however, I do.

I set a print(current_user.is_authenticated) to see what the value is and it always is False. I cannot figure it out. Any help would be appreciated.

from flask import Flask, render_template, redirect, url_for, Blueprint, request, flash
from flask_login import LoginManager
import os

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, EmailField
from wtforms.validators import DataRequired, Email

from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import UserMixin, LoginManager, login_user, login_required, current_user

import pymongo

app = Flask(__name__)

app.config['SECRET_KEY'] = '12345'

myclient = pymongo.MongoClient("thegoodstuff")
mydb = myclient["dbb"]
mycol = mydb["db"]

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

class User(UserMixin):
    def __init__(self, user_json):
        self.user_json = user_json
        
    #Overriding get_id is required if you don't have the id property
    # Check the source code for UserMixin for details
    def get_id(self):
        object_id = self.user_json.get('_id')
        return str(object_id)
    
    def is_authenticated(self):
        return self.authenticated
    
@login_manager.user_loader
def load_user(user_id):
    u = mycol.find_one({"_id": user_id})
    if not u:
        return None
    return User(u)

class LoginForm(FlaskForm):
    username = StringField('Username',validators=[DataRequired()])
    password = PasswordField('Password', validators=[DataRequired()])
    submit = SubmitField('Login')
    
class SignUp(FlaskForm):
    username = StringField('Username',validators=[DataRequired()])
    password = PasswordField('Password', validators=[DataRequired()])
    email = EmailField('Email', validators=[DataRequired(), Email()])
    submit = SubmitField('Register')

@app.route("/")
def homepage():
    form = LoginForm()
    return render_template('index.html', form=form)

@app.route("/login", methods=['POST'])
def login_post():
    
    username = request.form.get('username')
    password = request.form.get('password')
        
    user = mycol.find_one({"username": username})

    if not user or not check_password_hash(user['password'], password):
        flash('Please check your login details and try again.')
        return redirect(url_for('homepage'))
    
    loginuser = User(user)
    login_user(loginuser, remember=True)
    return redirect(url_for('profile'))
    
@app.route("/register")
def register():
    form = SignUp()
    return render_template('register.html', form=form)

@app.route("/register", methods=["POST"])
def register_post():
    
    email = request.form.get('email')
    username = request.form.get('username')
    password = request.form.get('password')
        
    user = mycol.find_one({"email": email})
    
    if user:
        flash('Email address already exists. Please login below.')
        return redirect(url_for('homepage'))
    
    mycol.insert_one({"username": username, "email": email, "password": generate_password_hash(password, method='sha256')})
    
    return redirect(url_for('homepage'))

@app.route("/profile")
@login_required
def profile():
    return render_template('profile.html')

So it looks like my issue was related to my user_loader .

My database query was always returning None as no record was found. This is because MongoDB defines the _id as an object ID, and not a str , I assume.

I imported ObjectId from bson.objectid and modified my user_loader to:

@login_manager.user_loader
def load_user(user_id):
    u = mycol.find_one({"_id": ObjectId(user_id)})
    if not u:
        return None
    return User(u)

This solved my issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM