python - Flask 登录 - @login_manager.token_loader 未被调用

标签 python flask flask-login

我正在尝试使用 token 对用户进行身份验证。

我已经设法让这个过程使用:

@login_manager.user_loader
def load_user(userid):
    from models import User
    return User.get(userid)

但是我不知道如何在使用 token 时让进程正常工作。

在我的 views.py 文件中,我有:

from flask import request, jsonify, url_for, render_template, session

@login_manager.token_loader
def load_token(token):

    # Check token and return user

当我登录用户时:

def _do_login_user(user):
    # User must have been authenticated
    if not user: raise_error('user does not exist', 'A user with this email address does not exist', 404)     

    # Check if user account is enabled
    if not user.is_active:
        raise_error('inactive account', 'Your account has not been enabled. Check your email Inbox and Spam folders for the confirmation email', 401)

    # Use Flask-Login to sign in user
    login_user(user)

    return json.dumps({"data":{"success":"true", "message":"You have logged in successfully!"}})

用户模型

class User(db.Model, UserMixin):

    def get_auth_token(self):
        s = Serializer(app.config['SECRET_KEY'], expires_in = 6000)
        return s.dumps({'id': self.id, 'password': self.password})

我应该在什么时候调用 User.get_auth_token() 并且我应该在 session 中手动设置这个 token ?

@login_manager.token_loader 最后什么时候被调用?

感谢您的帮助。

最佳答案

``@login_manager.token_loader` 是关于“记住我”的功能。

只有当浏览器访问您的站点时没有 session cookie 并且用户之前使用 login_user(user, remember=True) 登录时才会调用它。

您可以通过以下方式刺激 flask-login 调用您的 token_loader 装饰函数:

  • 使用“记住我”登录
  • 关闭浏览器
  • 再次打开浏览器并导航到“login_required”页面

...或使用此答案末尾的代码之类的东西。

您不需要自己调用 User.get_auth_token()。当您调用 login_user(user, remeber=True) 并定义了一个 @login_manager.token_loader

时,Flask-login 将调用它

查看 LoginManager._set_cookieLoginManager._load_from_cookie 以了解 Flask-Login 如何执行所有这些操作。

您的 _do_login_user 函数调用 login_user 而没有 remember=True 因此没有调用任何“记住我”功能。

下面是一些代码,用于说明何时调用相关函数:

from flask import Flask
from flask.ext.login import LoginManager, UserMixin, login_user, login_required

app = Flask('foo')
app.config['SECRET_KEY'] = 'abcd'
login_manager = LoginManager(app)


class User(UserMixin):
    def get_id(self):
        return 1

    def get_auth_token(self):
        print("get_auth_token called")
        return 'my_auth_token'


@login_manager.token_loader
def my_token_loader(token):
    print("my_token_loader called")
    return User()


@app.route('/login')
def login():
    login_user(User(), remember=True)
    return ''


@app.route('/protected')
@login_required
def protected():
    return ''


with app.test_client() as tc:
    # login will set session cookie as well as remember me cookie
    # User.get_auth_token will be called because we have defined a token_loader
    tc.get('/login')

    # clear the session cookie so the next request will use remember me
    tc.cookie_jar.clear_session_cookies()

    # our token_loader function should be called now as Flask-Login attempts to
    # log us in with the remember me cookie
    tc.get('/protected')

关于python - Flask 登录 - @login_manager.token_loader 未被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35125610/

相关文章:

python - 一张图片上的多个图表(python)

python - Flask-如何处理URL中的中文字符

python - 如何将表单数据传递到多个sqlite3行

python - 你如何守护一个 Flask 应用程序?

python - Pycharm:如何调整变量/语法突出显示的颜色?

python - 带有自定义 id 函数的 pytest 参数化测试

jquery - 如何使用 Flask、Ajax 的基本身份验证在浏览器中存储 token

python - 如何从 Flask-KVSession 中删除特定 key (针对当前 session )?

python - Flask 登录和 Heroku 问题

python - 如何在嵌套函数中共享函数变量?