Flask Login Manager登录后重定向回原页面问题求助
你的核心问题是:当Login Manager将用户重定向到登录页时,URL中已经携带了正确的next参数(比如/arm_analyst),但登录表单的action属性使用了request.endpoint(此时该值为login)生成新的next参数,导致表单提交时,原本正确的next被覆盖成了login,最终无法跳转到目标页面。
1. 修正表单的next传递方式
不要在表单action中用request.endpoint生成next,而是直接复用当前URL中已有的next参数,或者将next作为隐藏字段嵌入表单,确保提交时能保留原始的跳转目标。
方案A:复用URL中的next参数到表单action
修改表单的action属性,从当前请求的查询参数中获取next,如果没有则默认设为根路径:
<form action="{{ url_for('login', next=request.args.get('next', '/')) }}" method="post" class="card-body cardbody-color p-lg-5"> <!-- 原有输入框内容不变 --> <div class="mb-3"> <input type="text" class="form-control" name="login" placeholder="login" required> </div> <div class="mb-3"> <input type="password" class="form-control" name="password" placeholder="password" required> </div> <div class="text-center"> <button type="submit" class="btn btn-success px-5 mb-5 w-100">log in</button> </div> </form>
方案B:添加隐藏字段传递next(更推荐)
在表单内部添加一个隐藏输入字段,直接存储当前URL中的next值,这样不管表单提交到哪里,next都会被携带到后端:
<form action="{{ url_for('login') }}" method="post" class="card-body cardbody-color p-lg-5"> <input type="hidden" name="next" value="{{ request.args.get('next', '/') }}"> <!-- 原有输入框内容不变 --> <div class="mb-3"> <input type="text" class="form-control" name="login" placeholder="login" required> </div> <div class="mb-3"> <input type="password" class="form-control" name="password" placeholder="password" required> </div> <div class="text-center"> <button type="submit" class="btn btn-success px-5 mb-5 w-100">log in</button> </div> </form>
2. 修正后端next_page的获取逻辑
因为POST请求时,next参数会通过表单提交(方案B),或者仍在查询参数中(方案A),所以后端需要同时从request.args和request.form中获取next,确保两种场景都能正确拿到值:
@server.route("/login", methods=['GET', 'POST']) def login(): username = request.form.get('login') password = request.form.get('password') # 优先从查询参数取,没有则从表单取,最后默认根路径 next_page = request.args.get('next') or request.form.get('next') or '/' if current_user.is_authenticated: flash('You are already logged in!') return redirect(url_for('profile')) if username and password: user = User.query.filter_by(username=username).first() if not user: flash('incorrect login') return render_template('flask_user/login.html') if check_password_hash(user.password, password): login_user(user, remember=True) return redirect(next_page) else: flash('incorrect password') else: flash('Enter login and password') return render_template('flask_user/login.html')
3. 修正未授权处理器的重定向代码
你的unauthorized_handler中存在参数传递错误,redirect的next参数应该作为url_for的关键字参数传入,而不是单独作为redirect的参数:
@login_manager.unauthorized_handler def redirect_to_signin(response): # 将next作为url_for的参数,生成带next的登录页链接 return redirect(url_for('login', next=request.endpoint))
你之前在表单action中用request.endpoint,当用户访问登录页时(此时请求的endpoint是login),生成的next值就是login,完全覆盖了Login Manager传递过来的原始next参数,导致登录成功后跳转到登录页本身,而非目标页面。
内容的提问来源于stack exchange,提问作者foodshare

