flask-security icon indicating copy to clipboard operation
flask-security copied to clipboard

'next' parameter fails with blueprint endpoints (e.g. "User.view")

Open nk9 opened this issue 5 years ago • 0 comments

The login view is a NextFormMixin subclass, so it accepts a next parameter. As I understand it, the parameter can be a URL, a path or an endpoint. If you use a simple endpoint like "index", it works as expected and redirects to the provided endpoint on login.

However, endpoints in a blueprint have a period, like "User.profile". If you pass this kind of endpoint to 'next', the login view will treat it like a path and send you to e.g. http://localhost:4000/User.profile. This happens because validate_redirect_url() returns True for the blueprint endpoint. This, in turn, means that get_post_action_redirect() will use the very first URL in its list, which is just the raw endpoint name. It doesn't get to the 3rd element of the list, which is the result of get_url(request.form.get('next')) and is the correct path.

I am not sure what the right solution to this problem is. Perhaps the declared value should be compared with a list of the application's registered endpoints either in validate_redirect_url() or just before it's called. Or perhaps declared should be added later in the list so that the resolved endpoint will be evaluated first. URLs should return None when passed to get_url(), so while this will change precedence, it shouldn't change the outcome. Paths which contain a slash should work the same. Is there a similar API which we can model the behavior on?

As a workaround, I'm using the request's path in my decorator instead of passing the endpoint.

return redirect(url_for('security.login', next=request.path))

nk9 avatar Jun 25 '19 19:06 nk9