1
votes

I'm building a Flask app which uses Stormpath and Flask-Stormpath for auth. I wish to prevent a logged in user from accessing the /login or /register pages (since this doesn't make much sense - a logged in user has no need to log in, and you are registered by definition if you are already logged in). I have attempted a solution in my custom login page template, doing something along the lines of:

{% block page_heading %}

    {% if user.given_name %}
        Already Logged in as {{ user.given_name }}
    {% else %}
        Enter your credentials
    {% endif %}

{% endblock page_subheading %}

If a user is currently signed in, user.given_name will be defined and the page_heading block will take the 'already logged in' message, and otherwise the 'enter your credentials' message (in the normal case of an unauthenticated user going attempting to log in). I use the same construct to show the login form or more error text. However, this attempt does not work: it is as though user.given_name always reverts to undefined when a logged in user visits /login. This implies that if someone is logged in, and visits /login they are then logged out - this would explain the failure of my attempt at a solution.

Given the above and after consulting the docs, I might be able to use is_authenticated(); not through Flask-Stormpath, however, but through the underlying Flask-Login module, since Flask-Stormpath always sets this to return True, per the docs, but I have no idea how to go about this.

Additionally, my approach is hacky - I feel a better solution would reside in the Python side of the app.

So my question is this: What is the most sensible way to detect a user is logged in and given this, prevent them from accessing, or redirect them from, the /login and /register pages? Perhaps there is a magical decorator somewhere that is the opposite to

@login_required 

or a stormpath built-in 'unauthorised' group that I could use as in

@groups_required(['unauthorised'])

Or, maybe I was on the right lines with my original attempt.

Any help is appreciated :)

2
Update: I have just tried my original approach (the template based solution) with the /register page and got the desired behaviour. Things still don't work for /login. Looking more and more likely that if a logged in user visits /login, they are logged out, and then the login page is shown. Not sure how to deal with thisonyx__onyx

2 Answers

0
votes

Heyo!

So, I'm the author of Flask-Stormpath, I thought I'd jump in here. Instead of trying to modify the behavior of login / register (which I wouldn't recommend, as we change that stuff periodically with library releases), a better solution is to simply hide those URLs from the user once they've logged in.

Many websites have a top navbar, for instance, which initially says "Login" and "Register" somewhere. But, once you've logged in, those buttons change to something else, usually "Dashboard" or similar.

This way, a user isn't able to go to /login or /register unless they specifically type into the browser and attempt to go there manually.

I think this is the ideal scenario, which you can accomplish using template conditional logic:

{% if user %}
...
{% else %}
...
{% endif %}
0
votes

You can create a decorator containing the code below. It will redirect logged in users to another page if they try to access the login page.

if current_user.is_authencticated():
    return redirect (url_for('home'))