Flask登录@Login_manager.token_加载程序不被召唤

2024-04-24 23:28:21 发布

您现在位置:Python中文网/ 问答频道 /正文

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

我使用以下方法成功地使流程正常运行:

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

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

{cd2>我的文件中有:

^{pr2}$

登录用户时:

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中手动设置这个令牌?在

最后,@login_manager.token_loader何时被调用?在

谢谢你的帮助。在


Tags: 用户inselftokengetreturnifemail
2条回答

我也曾试过让这个工作正常,但后来我放弃了使用普通的user_loader,我唯一能建议的就是看看这里flask-login并检查实际代码,从中你可以看到它在会话中添加了用户标识,这样你就不用管它了。在

不管怎么说,我花了很多时间试图让它工作,最后我选择了类似于jwt and flask-login的东西

@login_manager.user_loader
def load_user(token):
    try:
        id = jwt.decode(token, current_app.config.get(
            'KEY', None))['_id']
        return user_functions.get_user_by_id(id, token)
    except (ServiceUnavailable, ServiceResponseError) as e:
        current_app.logger.exception(e.message)
        return None



class Login(MethodView):

    methods = ['GET', 'POST']

    def post(self):
        form = LoginForm(request.form)
        registered_user = form.validate()
        if not registered_user:
            return render_template('pages/login.html', login_form=form), 403
        login_user(registered_user, remember=False)
        return redirect(request.args.get('next') or url_for('public.index'))

不知道这有多大帮助,但当你失去耐心时值得一读

``@登录_manager.token_加载程序`都是关于“记住我”的功能。在

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

您可以通过以下方式刺激flask login调用token_loader decorated函数:

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

…或者使用类似于答案末尾的代码。在

您不需要自己调用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函数在没有remember=True的情况下调用login_user,因此不会调用任何“记住我”功能。在

下面是一些代码,应该说明调用相关函数的时间:

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')

相关问题 更多 >