IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    Cookie与Session

    Timmy (zhu327@qq.com)发表于 2015-01-31 11:23:21
    love 0

    前面学习了Cookie,知道Cookie是在浏览器端保存的用户状态,但是对Session一直没什么概念。学习Django的过程中直接使用了Django的认证系统,虽然用到了Session但是没有接触到Session的直接使用,然后在学习F2E.im的代码中,发现Tornado自带的secret cookie其实也能加密传递cookie,通过cookie传递一个userid到用户浏览器,认证的时候使用userid到数据库中查找用户信息,也能很好的认证用户。那为什么要使用session呢。

    Tonado中认证示例:

    # 重写tornado.web.RequestHandler中get_current_user方法用于认证
    def get_current_user(self):
        user_id = self.get_secure_cookie("user")
        if not user_id: return None
        return self.user_model.get_user_by_uid(int(user_id)) # 从数据库中取用户信息
    

    带着疑惑询问了某同事,得到了一个比较靠谱的答案。

    如上面的示例代码,在验证了用户名密码后,登录就把Cookie发送给用户:

    self.set_secure_cookie("user", str(user_id)) # Tornado中设置Cookie
    

    logout时清除Cookie:

    self.clear_cookie("user")
    

    但是这里有个问题即使这个Cookie是已经加密过的,但是只要加密密钥不变,这个Cookie如果被截取下来,clear_cookie只会清空当前浏览器的Cookie,不保证Cookie被有心的保存下来,如果继续使用被保存下来的Cookie,服务器是不会知道这个在有效时间内的Cookie是不是真的被退出。

    那么问题来了,怎么样保证用户登出后,Cookie实效呢,答案是用随机Cookie,使用Session,通过session保存一个随机Cookie作为key,value为用户id或者其它什么用户信息,用户登录的时候生成随机字符串,一般用sessionid作为Cookie的key,随机字符串作为value发送给用户,在Session中用这个随机字符串作为key,vaule为用户信息,在这个session有效时,首先是到session中获取用户信息。比如这样:

    def get_current_user(self):
        sessionid = self.get_secure_cookie("sessionid")
        if not sessionid: return None
        user_id = seesion.get(sessionid, None) # 先从seesion中获取用户信息
        if not user_id: return None
        return self.user_model.get_user_by_uid(int(user_id)) # 从数据库中取用户信息
    

    登录:

    sessionid = session.id() # 假设有这么一个生成随机字符串的方法
    session.set(sessionid, userid)
    self.set_secure_cookie("sessionid", str(sessionid))
    

    登出:

    session.delete(sessionid)
    self.clear_cookie("sessionid")
    

    这样即使sessionid被盗取,只要用户登出后,这个sessionid就失效了,就不会有Cookie在有效期内一直有效的问题了。

    从以上示例就可以看出session实现了什么功能:

    1. session是在服务端保存用户状态的东西
    2. session是 key-value存储信息的
    3. session有一个实现随机字符串的方法


沪ICP备19023445号-2号
友情链接