Flask login @login_required not working

2019-07-15 02:02发布

I'm using flask-login to make sure users are logged in before they can access certain pages. I'm using @login_required on the view I want to protect, but even though I'm setting login_user(user) where I'm wanting to set the user, it does not let me go into my protected route (index). I'm printing out the value of my user_login(user) and it returns True. What am I doing wrong?

@app.route('/')
@app.route('/index')
@login_required
def index():
    print("was in here", file=sys.stderr)
    return render_template('index.html')

This is the route where I set the user_login(user)

@app.route('/authenticate')
def authenticate():
    code = request.args.get('code')
    state = request.args.get('state')
    quiz_auth_response = quizlet_auth(code, state)

    g.token = quiz_auth_response['token']

    response = json.loads(make_request(quiz_auth_response['user_name']))

    try:
        user = models.User.get(models.User.username == response['username'])
        login_user(user)
    except models.DoesNotExist:
        print("does not exist", file=sys.stderr)
        user = models.User.create_user(response['username'], response['id'])
        return redirect('/index')
    else:
        login_user(user)
        print("log in user " + str(login_user(user)), file=sys.stderr)
        login_user(user)
        return redirect('/index')

Here is my user_loader

@login_manager.user_loader
def load_user(userid):
    try:
        return models.User.get(models.User.id == userid)
    except models.DoesNotExist:
        return None

Here is my User model

sqlite_db = SqliteDatabase('sqlite.db')

class BaseModel(Model):
    class Meta:
        database = sqlite_db

class User(UserMixin, BaseModel):
    username = CharField(unique=True)
    quizlet_id = CharField(unique=True)
    joined_at = DateTimeField(default=datetime.datetime.now)

    @classmethod
    def create_user(cls, username, quiz_id, **kwards):

        try:
            cls.select().where(
                (cls.username == username) | (cls.quizlet_id == quiz_id)
            ).get()
        except cls.DoesNotExist:
                print("putting user in thing", file=sys.stderr)
                user = cls(username = username, quizlet_id = quiz_id)

                print(user.username)
                user.save()
                return user
        else:
            raise Exception("User with that email exists already")

    @staticmethod
    def set_password(password):

        return generate_password_hash(password.encode('utf-8'))

4条回答
Rolldiameter
2楼-- · 2019-07-15 02:32

If you are using flask-login, you need to make sure that you have a function that can be used by the library to load a user based on the ID. Something of this type:

@login_manager.user_loader
def load_user(user_id):
    return models.User.get(models.User.id == user_id)

Please read this section of the docs for how to do it.

查看更多
迷人小祖宗
3楼-- · 2019-07-15 02:35

Just spent the last 2 hours trying to fix this and realized that it was because off the configuration that the login_required was not working

On my local development environment, I had set

app.config['TESTING'] = True

From the flask-login documentation

If the application configuration variable LOGIN_DISABLED or TESTING is set to True, the login_required decorator will be ignored

set it back to this and got it working

app.config['TESTING'] = False

查看更多
Fickle 薄情
4楼-- · 2019-07-15 02:38

My problem was that the @flask_login.login_required decorator was above the @app.route('<path>') decorator, so I just replaced them and it worked

From this:

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

to this:

@app.route('/')
@flask_login.login_required
def index():
    return render_template("index.html")
查看更多
Deceive 欺骗
5楼-- · 2019-07-15 02:43

Is the username field a primary key? Assuming that you are using sql alchemy, the get() method aways look for the primary key and does not accept expressions, see http://docs.sqlalchemy.org/en/rel_1_0/orm/query.html#sqlalchemy.orm.query.Query.get

Try again with user = models.User.filter_by(username=response['username'])...

查看更多
登录 后发表回答