0

Here is the situation:

I have an app which includes a user login feature.

The problem I have is this:

When a user logs in / fails an attempt to login and a user object is created. For the one user,it conforms to the expected behavior of:

  1. Go to a page while not logged in EXPECT redirect to login page.
  2. Give incorrect login information not a 5th attempt or beyond EXPECT redirect to login page.
  3. Incorrect login information given a 5th time or beyond, EXPECT redirect to fatal login error message from any route attempted, no further login attempts to be accepted.
  4. Correct login information given EXPECT content is made visible for all routes

The problem I am trying to fix is that when one user is logged in, this is interpreted in the context of all user sessions, not the session that was created by that user. Once one user is logged in, all users attempting to access the app are given access until that user logs out, without the subsequent users having to enter the password.

So I have the class like this which serves as a user object:

class User:
    def __init__(self,password,user_name)
        self.password = some_password_hashing_method(password)
        self.username = user_name
        self.loggedin = False
        self.passwordguesses = 0

This is the functionality that evaluates a login request. It will start by checking if there is a user object (should be on a session by session basis), and if non-existant, it instantiates the object per the login request and checks the values against the list of hashed passwords via the hashing algorithm used.

It works with one user, but the problem is that when one user logs in then a second user enters the app from another computer with a different IP address, it does not create a new User object. It will see that the existing user.loggedin is set to True, and will treat the user as if they were logged in when they are not, another user is logged in.

How do I make Python treat this variable as an instance variable that will be generated once each time a new user session is created?

@app.route('/verifylogin',methods = ['POST']) 
def verifylogin():
    checksPassword = g.readcsv('filewithpasswords.csv')
    usersList = g.readcsv('filelistingusers.csv')
    global user
    try:
        the_user.passwordguesses
    except NameError:
        user = User(request.form['userid'],request.form['password'])
    i = 0
    if user.password_guesses < 5:
        while i < len(checksPassword):
            if somehashcheckingmethod(checksPassword[i][0], request.form['password']) and usersList[i][0] == request.form['userid']:
                user.loggedin = True
                return redirect('/index')
            i += 1
        user.passwordguesses += 1
        return redirect('/login')
     else:
         return render_template('fatal.html') 

Lastly, here is the redirect header which is included at the beginning of all pages. The expected behavior is to 1. check if there is an active user session for that user, and if not, then they are redirected to the login route. 2. It will check if the current user is logged in, and if not, they are redirected to the login page as well. 3. if neither of these are true, it moves on to the subsequent lines of code and provides access to the content.

try:              
    user.isloggedin
except NameError:
    return redirect('login') 
if user.isloggedin != True:
    return redirect('login')

Again, there is apparently a problem with the context this code is being interpreted in, because it is applying the logged in status of one user to all subsequent user sessions.

Please note that commenting out the following line does not correct this issue:

global user

Once this is commented out, this alters the scope of the user object to be only within the scope of the function verifylogin() wherein it was declared.

So if I write a new route and the function to render its content, now the object 'user' is outside the scope of the function I am writing to render the content for the new route:

@app.route('/index.html')
def index():    
    try:              
        user.isloggedin
    except NameError:
        return redirect('login') 
    if user.isloggedin != True:   # this code and all code below it is unreachable, because you will always get a NameError exception from the above lines of code. This is not a duplicate.
        return redirect('login')
    return render_template('index.html')
Davidt
  • 11
  • 3

1 Answers1

0

This is usually accomplished in the web by using sessions delivered through secure cookies.

https://blog.miguelgrinberg.com/post/how-secure-is-the-flask-user-session

A session is a secure (hopefully) cookie that your app will provide each client. Your app should be able to generate a persistent individual session that will last for as long as the session is alive. For many of the popular web frameworks the only thing that the cookie contains is a session ID. This way you can store persistent state for the user and use their session ID as a reference.

dm03514
  • 54,664
  • 18
  • 108
  • 145