How to get through the β€œnext” URL using a checkbox and checkbox?

The documentation for Flask-login talks about handling the "next" URL. The idea seems to be:

  • User goes to /secret
  • The user is redirected to the login page (e.g. /login )
  • After a successful login, the user is redirected back to /secret

The only semi-complete example of using a flash drive I found is https://gist.github.com/bkdinoop/6698956 . This is useful, but since it does not contain HTML template files, I see if I can recreate them as a self-learning exercise.

Here's a simplified version of the /secret and /login sections:

 @app.route("/secret") @fresh_login_required def secret(): return render_template("secret.html") @app.route("/login", methods=["GET", "POST"]) def login(): <...login-checking code omitted...> if user_is_logged_in: flash("Logged in!") return redirect(request.args.get("next") or url_for("index")) else: flash("Sorry, but you could not log in.") return render_template("login.html") 

And here login.html :

 <form name="loginform" action="{{ url_for('login') }}" method="POST"> Username: <input type="text" name="username" size="30" /><br /> Password: <input type="password" name="password" size="30" /><br /> <input type="submit" value="Login" /><br /> 

Now, when the user visits /secret , he is redirected to /login?next=%2Fsecret . So far so good - the "next" parameter is in the query string.

However, when the user submits the login form, he is redirected back to the index page, and not back to the /secret URL.

I assume that the reason is that the β€œnext” parameter, which was available on the incoming URL, is not included in the login form and therefore is not passed as a variable when processing the form. is the correct way to solve this problem?

One solution seems to work - change the <form>

 <form name="loginform" action="{{ url_for('login') }}" method="POST"> 

in

 <form name="loginform" method="POST"> 

When the action attribute is removed, the browser (at least Firefox 45 on Windows) automatically uses the current URL, forcing it to inherit the query string ?next=%2Fsecret , which successfully sends it to the form processing handler.

But omits the form attribute "action" and allows the browser to fill it in the right solution? Does it work in all browsers and platforms?

Or is there a checkbox or checkbox to enter so that it is handled differently?

+7
python flask forms flask-login
source share
2 answers

If you need to specify a different action attribute on the form, you cannot use the following parameter provided by Flask-Login. I would recommend anyways to put the endpoint instead of url in the url parameter, since it is easier to check. Here is some code from the application I'm working on, maybe this may help you.

Overwrite the unauthorized handler with flags to use the endpoint instead of the URL in the following parameter:

 @login_manager.unauthorized_handler def handle_needs_login(): flash("You have to be logged in to access this page.") return redirect(url_for('account.login', next=request.endpoint)) 

Use request.endpoint in your own URLs:

 {# login form #} <form action="{{ url_for('account.login', next=request.endpoint) }}" method="post"> ... </form> 

Redirect to the endpoint in the next parameter, if it exists and is valid, otherwise redirect to reserve.

 def redirect_dest(fallback): dest = request.args.get('next') try: dest_url = url_for(dest) except: return redirect(fallback) return redirect(dest_url) @app.route("/login", methods=["GET", "POST"]) def login(): ... if user_is_logged_in: flash("Logged in!") return redirect_dest(fallback=url_for('general.index')) else: flash("Sorry, but you could not log in.") return render_template("login.html") 
+5
source share

@timakro provides a neat solution. If you want to process a dynamic link, for example

Index / <& user GT;

and then use request.path because request.endpoint will not contain dynamically accessible information:

  @login_manager.unauthorized_handler def handle_needs_login(): flash("You have to be logged in to access this page.") return redirect(url_for('account.login', next=request.path)) 

The following code should be changed to:

 def redirect_dest(home): dest_url = request.args.get('next') if not dest_url: dest_url = url_for(home) return redirect(dest_url) @app.route("/login", methods=["GET", "POST"]) def login(): ... if user_is_logged_in: flash("Logged in!") return redirect_dest(home=anyViewFunctionYouWantToSendUser) else: flash("Sorry, but you could not log in.") return render_template("login.html") 
+1
source share

All Articles