[Tornado]扫码登录实践

思路: 基于[Tornado]异步io实现异步非阻塞长链接。
复制代码

本文作者为
简书-melo的微博 / 掘金-melo的微博
Github-meloalright / Medium-@meloalright
转载请注明出处哦。

1.扫码登录需求

部门项目需要实现一个APP扫码即可在PC端实现登录的需求。
结合部门内部的资源协调,适合使用一个异步io的框架实现简单扫码登录接口快速上线。
初期考虑使用[node.js]或者[Tornado]
最终选择使用[Tornado]
复制代码

2.实现思路

- 基于 uuid.uuid4() 为二维码生成唯一 uuid
- 基于 tornado.locks 实现长链接 handler 协程的通知等待
- 基于 await http_client.fetch 实现扫码确认请求handler的内部校验接口调用
复制代码

3.代码结构

│ 
│   # @ Python Tornado 工程代码
│ 
├── tornado-project
│   │
│   │   # @ 各种handler放这里
│   │
│   ├── handlers
│   │   │ 
│   │   ├── __init__.py
│   │   │ 
│   │   ├── confirm_handler.py # 确认扫码请求的handler
│   │   │ 
│   │   │ 
│   │   ├── uuid_handler.py # 获取uuid请求的handler
│   │   │ 
│   │   ├── wait_handler.py # 长链接请求的handler
│   │   │ 
│   │   │  # @ redis_map 放这里
│   │   │ 
│   │   └── redis_map 
│   │       ├── __init__.py
│   │       └── redis_map.py
│   │ 
│   ├── main.py # 入口文件
│   │ 
│   └── requirements.txt # 项目依赖
复制代码

4. wait_handler

/wait 长链接接口

class WaitHandler(tornado.web.RequestHandler):
    async def post(self):
        data = tornado.escape.json_decode(self.request.body)
        cursor = data["cursor"]

        status = int(RedisMap.get_status(cursor))
        '''
        some code ...
        '''

        while status < 2 and status > -1:
            self.wait_future = RedisMap.wait()

            try:
                await self.wait_future
            except asyncio.CancelledError:
                return

            status = int(RedisMap.get_status(cursor))
            '''
            some code ...
            '''


        if self.request.connection.stream.closed():
            RedisMap.delete(cursor) # delete
            return

        RedisMap.delete(cursor) # delete
        self.write({
            "status": status 
            '''
            other key value ...
            ''' 
        })

    def on_connection_close(self):
        self.wait_future.cancel()
复制代码

5. confirm_handler

/confirm 确认扫码登录接口


class ConfirmHandler(tornado.web.RequestHandler):

    async def auth(self, param):
        http_client = tornado.httpclient.AsyncHTTPClient()
        response = await http_client.fetch("An auth uri blau blau ..." , headers=param)
        '''
        some code ...
        '''
        response_data = tornado.escape.json_decode(response.body)
        return response_data['status'] is 200

    async def post(self):
        data = tornado.escape.json_decode(self.request.body)
        authorization = data["authorization"]
        '''
        some code ...
        '''
        is_auth = await self.auth(authorization)
        if not is_auth:
            self.write({
                "status": 401,
            })
            return
        else:
            self.write({
                "status": 200
                })
复制代码

结语:

代码只是示例 仅供参考哈(∩_∩)

鸣谢:

参考文档:
tornadoweb.org
tornado.locks – 同步原语

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值