【问题标题】:webPy Sessions - Concurrent users use same session and session timeoutwebPy Sessions - 并发用户使用相同的会话和会话超时
【发布时间】:2016-02-29 10:32:40
【问题描述】:

我有一个使用会话进行用户身份验证的 webPy 应用程序。会话是这样启动的:

web.config.debug=False

store = web.session.DiskStore('/path_to_app/sessions')
if web.config.get('_session') is None:
    web.config.session_parameters['ignore_expiry'] = False
    web.config.session_parameters['timeout'] = 600
    web.config.session_parameters['max_age'] = 600
    web.config.session_parameters['ignore_change_ip'] = False
    web.config.session_parameters['expired_message'] = 'Session Expired... Please reload the page and login in again.'
    web.config.session_parameters['cookie_name'] = 'my_session_id'
    session_init = web.session.Session(app, store, initializer={'login':0, 'privilege':0, 'user':'none'})
    session = session_init._initializer
    web.config._session = session
else:
    session = web.config._session

这里是登录类:

class Login:
    def GET(self):
        if logged() == True:
            return render.index()
        else:
            render = create_render(session['privilege'])
            return render.login()


    def POST(self):
        data= web.input()
        name = data['user']
        passwd = data['passwd']
        ident = model.get_users(m, name)
        try:
            if passwd == ident.password.strip():
                session['login'] = 1
                session['privilege'] = ident['privilege']
                session['user'] = name
                render = create_render(session['privilege'])
                return render.index()
            else:
                session.login = 0
                session.privilege = 0
                session.user = 'none'
                render = create_render(session['privilege'])
                return render.login()
        except:
            session['login'] = 0
            session['privilege'] = 0
            render = create_render(session['privilege'])
            return render.login()

这是记录的检查:

def logged():
    if session['login']==1:
        return True
    else:
        return False

我有两个无法解决的问题:

  1. 当存在与 Web 服务器的并发连接时,它们会使用相同的会话,因此如果有人已经登录,则另一个用于连接到该站点的人会直接跳转而无需身份验证。

更新:

实际上在磁盘存储中为每个用户创建了一个新会话,但除了 ID 之外的详细信息是相同的 - 问题仍然是新用户不需要身份验证:

>>> x = base64.b64decode(open("/path_to_app/sessions/71b598e8a40c62cc6b5a1bf7a380d67886e87859").read())
>>> pickle.loads(x)
{'privilege': 2, 'ip': u'137.237.225.56', 'login': 1, 'user': u'admin', 'session_id': '71b598e8a40c62cc6b5a1bf7a380d67886e87859'}
>>> 
>>> y = base64.b64decode(open("/path_to_app/sessions/5a7364dc2a23ea69c61212bc496500cbb15f89bd").read()) 
>>> pickle.loads(y)
{'privilege': 2, 'ip': u'137.237.225.133', 'login': 1, 'user': u'admin', 'session_id': '5a7364dc2a23ea69c61212bc496500cbb15f89bd'}
  1. 会话到期时,不会被删除。我可以看到会话到期并生成定义的消息,但如果用户刷新页面,他们会直接再次进入。有没有办法在会话到期时终止会话?

谢谢!

【问题讨论】:

    标签: python session cookies web.py


    【解决方案1】:

    我不喜欢把这个挂起来,以防未来有人发现这个并想知道我学到了什么......

    我最终放弃了 web.py 中的会话,并仅使用客户端 cookie 转移到了 Beaker 会话中间件。

    一个简单的例子:

    import web
    from beaker.middleware import SessionMiddleware
    
    urls = (
             '/', 'index',
             '/login', 'Login',
             '/logout', 'Logout'
            )
    
    t_globals = {
                 'datestr': web.datestr,
                 'str': str,
                 'datetime': datetime
                 }
    
    
    # beaker options are optional.... but it's good to see 
    # where they are called
    
    session_opts = {
        'session.cookie_expires': True,
        'session.timeout' : 600,
        'session.secure' : True,
    }
    
    # define webPy app
    app = web.application(urls, globals())
    
    # smash it all together and define name for cookie key (sid)
    def session_mw(app):
        return SessionMiddleware(app, config = session_opts, key = "sid")
    
    
    
    # function to check if we are logged in
    def logged(session):
        if 'login' in session:
            if session['login']==1:
                return True
            else:
                return False
        else:
            return False
    
    # create different renders based on log in privilege
    def create_render(privilege):
        session = web.ctx.environ['beaker.session']
        if logged(session) == True:
            if privilege == 0:
                render = web.template.render('/templates/user/', base='user_base', globals=t_globals)
            elif privilege == 1:
                render = web.template.render('/templates/user/', base='user_base', globals=t_globals)
            elif privilege == 2:
                render = web.template.render('/templates/admin/', base='base', globals=t_globals)
            else:
                render = web.template.render('/templates/viewer/', base='base', globals=t_globals)
        else:
            render = web.template.render('templates/', globals=t_globals)
        return render
    
    class Login:
        def GET(self):
            session = web.ctx.environ['beaker.session']
            if logged(session) == True:
                render = create_render(session['privilege'])
                return render.index()
            else:
                render = create_render(0)
                return render.login()
    
    
    
       # I get user credentials from a database (called in model.get_users) 
            def POST(self):
                session = web.ctx.environ['beaker.session']
                data= web.input()
                name = data['user']
                passwd = data['passwd']
                ident = model.get_users(m, name)
                try:
                    if passwd == ident.password.strip():
                        session['login'] = 1
                        session['privilege'] = ident['privilege']
                        session['user'] = name
                        session.save()
                        render = create_render(session['privilege'])
                        return render.index()
    
                    else:
                        session.login = 0
                        session.privilege = 0
                        session.user = 'none'
                        render = create_render(session['privilege'])
                        return render.login()
                except:
                    session['login'] = 0
                    session['privilege'] = 0
                    render = create_render(session['privilege'])
                    return render.login()
    
        class Logout:
            def GET(self):
                session = web.ctx.environ['beaker.session']
                try:
                    render = create_render(0)
                    session.invalidate()
                    session.delete()
                    return render.logout()
                except:
                    session.invalidate()
                    session.delete()
                    render = create_render(0)
                    return render.logout()
    
    
        class index:
            def GET(self):
                session = web.ctx.environ['beaker.session']
                if logged(session) == False:
                    raise web.seeother('/login')
                else:
                    render = create_render(0)
                    return render.index()
    
    
        if __name__ == "__main__":
            app.run(session_mw)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-22
      • 2015-10-10
      • 1970-01-01
      • 2013-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多