如何让python为每个会话创建一个新的类实例?

时间:2017-07-18 16:36:01

标签: python flask scope

情况如下:

我有一个包含用户登录功能的应用。

我遇到的问题是:

当用户登录/失败时,尝试登录并创建用户对象。对于一个用户,它符合预期的行为:

  1. 在未登录EXPECT重定向到登录页面的情况下转到页面。
  2. 提供错误的登录信息,而不是第5次尝试或超出EXPECT重定向到登录页面。
  3. 第5次或更高时间的登录信息不正确,EXPECT重定向到尝试的任何路由的致命登录错误消息,不再接受登录尝试。
  4. 如果所有路线都显示EXPECT内容,则输入正确的登录信息
  5. 我想解决的问题是,当一个用户登录时,会在所有用户会话的上下文中解释,而不是该用户创建的会话。一个用户登录后,所有试图访问该应用程序的用户都将获得访问权限,直到该用户注销,后续用户无需输入密码。

    所以我有这样的类作为用户对象:

    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
    

    这是评估登录请求的功能。它将首先检查是否存在用户对象(应基于会话),如果不存在,则根据登录请求实例化对象,并通过散列算法检查散列密码列表中的值用过的。

    它适用于一个用户,但问题是当一个用户登录然后第二个用户从具有不同IP地址的另一台计算机进入该应用程序时,它不会创建新的用户对象。它会看到现有的user.loggedin被设置为True,并且会将用户视为已登录,如果不是,则另一个用户已登录。

    如何让Python将此变量视为每次创建新用户会话时生成的实例变量?

    @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') 
    

    最后,这里是重定向标题,它包含在所有页面的开头。预期的行为是1.检查该用户是否有活动的用户会话,如果没有,则将其重定向到登录路由。 2.它将检查当前用户是否已登录,如果没有,则会将其重定向到登录页面。 3.如果这些都不是真的,它将转移到后续的代码行并提供对内容的访问。

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

    同样,这个代码被解释的上下文显然存在问题,因为它将一个用户的登录状态应用于所有后续用户会话。

    请注意,注释掉以下行并不能解决此问题:

    global user
    

    一旦注释掉,这就会改变用户对象的范围,使其仅在声明它的函数verifylogin()的范围内。

    因此,如果我写一个新的路线和渲染其内容的功能,那么现在对象&#39;用户&#39;超出我正在编写的函数的范围,以呈现新路径的内容:

    @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')
    

1 个答案:

答案 0 :(得分:0)

这通常是通过使用sessions提供的secure cookies在网络上完成的。

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

会话是一个安全(希望)的cookie,您的应用将为每个客户提供。您的应用应该能够生成一个持久的单个会话,只要会话处于活动状态,该会话将持续一段时间。对于许多流行的Web框架,cookie包含的唯一内容是会话ID。这样,您可以为用户存储持久状态,并使用其会话ID作为参考。