首页 文章

Flask-login不会重定向到上一页

提问于
浏览
8

考虑到这一点,我已经看到了很多问题,但未能解决我的问题 . 我有一个带烧瓶登录的Flask应用程序,用于会话管理 . 并且,当我尝试在没有登录的情况下查看页面时,我被重定向到 /login/?next=%2Fsettings%2F 形式的链接

问题是,据我所知,"next"参数保存了我实际需要的网站部分,但在向登录表单提交请求时,它是通过 POST 完成的,因此该参数不再可用让我重定向到 .

我尝试从Request(和url)使用 Request.path ,但两者都只返回 /login/ 作为请求url / path,而不是实际的 /login/?next=xxx .

我的登录方法如下:

@app.route('/login/', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        #getting the user
        user = User.get(request.form['username'])
        if user.user is None:
            return redirect('/login/')
        #actual login proces
        if user and check_password_hash(user.user.password, request.form['password']):
            login_user(user, remember=remember)
            #the redirection portion of the login process
            return redirect(request.path or ("/")) # I tried various options there but without success, like request.args['next'] and such

        return redirect('/login/')

    else:
        return redirect('/')

谢谢

2 回答

  • 1

    request.path不是你想要的 . 它返回URL的实际路径 . 因此,如果您的网址是 /a/?b=c ,那么 request.path 将返回 /a ,而不是 c ,正如您所期望的那样 .

    next 参数位于URL中的 ? 之后,因此它是"query string"的一部分 . Flask已经为您解析了查询字符串中的项目,您可以使用request.args检索这些值 . 如果您向URL /a/?b=c 发送了请求并执行 request.args.get('b') ,则会收到 "c" .

    所以,你想使用 request.args.get('next') . 文档shows how this works in an example .

    另外要记住的是,当您在HTML中创建登录表单时,您不希望设置“action”属性 . 所以,不要这样做..

    <form method="POST" action="/login">
        ...
    </form>
    

    这将导致POST请求发送到 /login ,而不是 /login/?next=%2Fsettings%2F ,这意味着您的 next 参数将不是查询字符串的一部分,因此您将无法检索它 . 您想要取消"action"属性:

    <form method="POST">
        ...
    </form>
    

    这将导致表单发布到当前URL(应该是 /login/?next=%2Fsettings%2f ) .

  • 17

    您可以使用mongoengine会话通过flask会话( from flask import session )传递'next_url'参数 . 在py文件中,您可以在其中定义应用程序和login_manager:

    from flask.ext.mongoengine import MongoEngineSessionInterface
    app.session_interface = MongoEngineSessionInterface(db)
    
    @login_manager.unauthorized_handler
    def unauthorized_callback():
        session['next_url'] = request.path
        return redirect('/login/')
    

    然后在登录视图中:

    def login():
        # ... if success
        next_url = session.get('next_url', '/')
        session.clear()
        return redirect(next_url)
    

相关问题