手写一个tornado框架session功能

手写一个tornado框架session功能

在web开发的时候因为我们经常需要用到cookie来识别和保存用户状态,但是cookie又不是很安全,很多信息直接明文就暴露了,这个时候session就派上用场了,而python web框架tornado就没有自带的session功能,这个时候我自己手撸一个出来,其实了解session的原理的话还是很好写的。

什么是session?

我们知道因为http连接是无状态的,客户端连接服务器请求完数据后便断开连接,下一次连接的时候服务器端便不知道你是谁,那么服务器要通过怎样知道你是谁呢,这个时候就需要cookie了,cookie等于是一个身份令牌,当你来请求服务器端的时候,服务器端会给客户端发一个令牌,而客户端下一次访问的时候,就可以带着这个令牌来访问服务端。这就是cookie的原理。打个比方当你通过账户密码登陆网站的时候,服务端就会往你的cookie里面写入,is_login=true, user_id=1这种方式来记录用户已经登陆。当你带着这个 cookie去访问服务端的时候,服务端就知道你已经登陆了,并且你是用户1。但是这种方式太简单粗暴了,不太安全。我们应该保证这类令牌是随机的不可预料性以保证其最基本的安全。

    了解cookie原理后再来看session原理,既然session可以解决安全等问题,他是如何做到呢?既然cookie将一些敏感数据简单粗暴的存储在客户端这样不安全,那session就是将数据存储在服务器端以便每次认证,并每次都会更新。

照着这个思路我们来看看代码部分

这里假设你已经完成了登陆功能,并创建了用户表。

首先在用户模型中添加一个字段(我的tornado项目用的model模块是peewee)

sessions            = peewee.CharField(db_column="sessions")

看看登陆是怎么处理的

        # 假设前面完成用户账户密码认证并获取到用户对象member_obj(从用户表中获取到的用户对象)
        # 生成10位的随机字符串
        sess_key = ''.join(
            random.choice(string.ascii_lowercase + string.digits) \
            for i in range(10)
        )
        # 将其保存到字典中
        session = {"id": sess_key, "time": int(time.time())}
        try:
        # 从用户表中读取存入的json数据并将其从json转为列表
            sessions = json.loads(member_obj.sessions)
        except:
            sessions = list()
        if not isinstance(sessions, list):
            sessions = list()
        # 将当前生成session key字典加入sessions list
        # 限制session list长度为5
        sessions.append(session)
        if len(sessions) > 5:
            sessions = sessions[-5:]
        将session list转为json存入用户表中的session列中
        member_obj.sessions = json.dumps(sessions)
        member_obj.save()
        # 将其写入cookie中,以便从cookie中获取数据后对其进行认证(这里其实暴露了member_id你可以对cookie value二次加密,我偷懒就没弄)
        self.set_cookie(self.settings["cookie_key_sess"],
            str(member_obj.member_id)+":"+sess_key
        )

然后我们可以对tornado的 RequestHandler的get_current_user进行重写(这是tornado预留的钩子函数,用户用户认证,详细可以看官方文档)

    def get_current_user(self):
        cookie_data = self.get_cookie(self.settings["cookie_key_sess"])
        if not cookie_data:
            return None

        try:
            telephone, session_id = cookie_data.split(":")
        except:
            return None
        #这个是我自己写的Member model下的classmethod
        member = Member.get_user_by_sess(member_id, session_id)
        return member


#Member model下的classmethod

   @classmethod
    def get_user_by_sess(cls, member_id, session_id):
        member = None
        sessions = None
        try:
            member = cls.get(
                (cls.member_id == member_id) & (cls.status == 'normal') #status是用户状态,判断是否被注销
            )
            sessions = json.loads(member.sessions)
        except:
            return None

        if not member or not sessions or not isinstance(sessions, list):
            return None

        for session in sessions: #判断用户携带过来的session数据是否有效,有效返回member对象
            if isinstance(session, dict) and session.get("id") \
                    and session["id"] == session_id:
                return member
        return None

 

转载于:https://my.oschina.net/u/3640109/blog/3031000

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/101008.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • C/C++ 命令解析:getopt 方法详解和使用示例

    C/C++ 命令解析:getopt 方法详解和使用示例一、简介getopt()方法是用来分析命令行参数的,该方法由Unix标准库提供,包含在<unistd.h>头文件中。 二、定义intgetopt(intargc,char*constargv[],constchar*optstring);externchar*optarg;externintoptind,opterr,o…

    2022年4月29日
    40
  • Android Studio获取开发版SHA1值和发布版SHA1值的史上最详细方法

    Android Studio获取开发版SHA1值和发布版SHA1值的史上最详细方法前言:今天我想把百度地图的定位集成到项目中来,想写个小小的案例,实现一下,但在集成百度地图时首先要申请秘钥,申请秘钥要用到SHA1值,所以今天就来总结一下怎样去获取这个值吧,希望对大家有帮助。 正常情况下:一、获取开发版SHA1:在此我直接用AndroidStudio提供的命令控制台了,毕竟做Android开发几乎都是用AndroidStudio了。1、打开androi…

    2022年8月11日
    9
  • 开发网络游戏的成本(经营成本与总成本区别)

    开发一个网络游戏以开发团队30人,开发周期18个月,人均月成本1万元计算.(这个是概数),约为540万.计算技术购买,测试服务器费用等等等等其他一切费用,普通国产网络游戏开发成本应该在600-1000万之间.运营成本.假设准备做到在线5万人,以平均10台服务器/组,5000人/组承载计算,约需10组,100台服务器.算上网站服务器,备用服务器等等,120台服务器投入是比较保守的估计.以单台平…

    2022年4月15日
    295
  • 搭建谷歌云

    搭建谷歌云GoogleCloud不需要任何money的,但是你需要你一张visa的信用卡,因为Google会验证账户的真实性,先从账户扣除1美元,过一会儿就会退回来的(一般5分钟左右)注意,搭建GoogleCloud的过程中,也是需要处于不被和谐的环境下的,至于如何获取Google账号,这里不做过多介绍。首先打开谷歌云,有账号就直接登录,没有就按照页面提示注册…

    2022年6月16日
    52
  • 【MySQL案件】ERROR 1665 (HY000)

    【MySQL案件】ERROR 1665 (HY000)

    2022年1月6日
    56
  • 提升网站权重的方法_怎么快速提升网站权重到4

    提升网站权重的方法_怎么快速提升网站权重到4SEO权重是各大搜索引擎给予网站赋予的评估或评价等级,代表着网站在某领域中的权威性、健康度及成长潜力,网站的权重越高一方面代表其越具权威性,另一方面也代表着搜索引擎对其友好度越强,会在排名、流量和信任度评价给予较好的扶持。权重是一个相对性的概念,即根据某既定指标的整体评价中相对的重要程度。如果用容易理解的方法来说,比如指数是量级统计数据,那么权重便是性质评估数据,互联网平台普遍存在指数和权重相关体系化的数据管理。一、SEO权重与网站的关系1.百度权重是第三方推出,收录与其没直接联系.

    2022年10月6日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号