Channels实现扫码登录
参考了下别人说的原理,根据自己的逻辑实现,没有完全按照别人的原理来,所以不一定适用于大家,仅供参考吧!!!
流程如下:
1. web发起websocket链接,后端接受链接后立马发送第一次消息,为全局唯一标识key
2. web收到第一次的消息,将字符串生成二维码展现出来
3. App进行扫码获取key,并当做参数调用后端接口,成功则App提示用户
3. 后端收到App的请求,成功处理(APP扫码成功)则向web发送第二次消息,为身份标识token,并关闭连接
4. web收到token,存到本地,再做登录成功的逻辑,就o了
Django实现websocket的包目前只了解到channels跟dwebsocket,channels维护得比较好,功能也强大一些,所以采用channels了
具体在与web的通讯中,怎么判断App是否扫码了,我是这样做的(仅供参考):
在后端生成key并第一次向web发送消息的时候,就存入将key存入redis,值为空。然后循环检测该值是否不为空,不为空就当做token发送给web,超时就提醒web。app扫码后调用后端接口时,后端就根据key将值设为身份token,前面循环检测到不为空,就...
当然,可以去掉循环检测,让app也走websocket,把整体当做一个聊天室,可能更好一点。但是由于某些原因,还是算了嘛
下面展示主要代码
跟Web通讯的代码:
from channels.generic.websocket import WebsocketConsumer
import time,random redis_helper = RedisHelper() # 自己的连接Redis工具类 # 扫码登录
class SaoLoginSync(WebsocketConsumer):
redis_hash_name = 'sao_login' # key存入redis1的hash结构名
def connect(self):
# 创建连接时调用
self.accept()
self.key = str(time.time()) + str(random.randint(0,9999)) # 用户id + 时间戳 + 随机数
redis_helper.hset(self.redis_hash_name, self.key, '')
self.send(text_data=self.key) # key发给web生成二维码 # 在此循环监听 app是否扫码了,扫码后吧生成的token发给web
token = False
start_time = time.time()
while not token:
token = redis_helper.hget(self.redis_hash_name, self.key)
if token:
self.send(text_data=token, close=True)
if time.time() - start_time > 120:
self.send(text_data='again', close=True) def disconnect(self, close_code):
# 连接关闭时调用
redis_helper.hdel(self.redis_hash_name, self.key) # 删除key
self.close()
App扫码之后调用的接口代码:
from rest_framework.decorators import api_view # 扫码完成通知
@api_view(['POST'])
@login_verify # 自己的登录验证装饰器,验证成功会加入user对象参数
def sao_code(request,user):
key = request.POST.get('key') # 扫码获取的key
redis_hash_name = 'sao_login' # key所在的hash结构名,与web通讯时一致
platform = 'web' # 平台
redis_helper = RedisHelper() if redis_helper.hexists(redis_hash_name, key): # 如果key存在
# redis存token
token = create_login_token(user.id, Platform[platform])
login_key = Platform[platform] + '_login_token_' + str(user.id)
redis_helper.set(login_key, token, ex=datetime.timedelta(days=30)) # 记录web的登录token
redis_helper.hset(redis_hash_name, key, token) # app 已经扫码完成,可以把token发送给web
code, msg = (100, 'Sao successfully')
else:
code, msg = (-1, 'Key does not exist') return ret_CORS(code, msg)
对了, 正式部署到服务器的时候,channels得用daphne启动,然后最好配置一下由nginx转发请求
Channels实现扫码登录的更多相关文章
- Web应用多账号系统设计及微信扫码登录实现
Web应用多账号系统设计及微信扫码登录实现 1 前言概述 公司对功能测试,性能测试,安全测试等等都做了比较好的自动化后,急需要一个MIS系统来统一管理这些结果及报表. 此MIS系统特点如下: 仅内 ...
- C#开发微信门户及应用(45)--微信扫码登录
在前面随笔<C#开发微信门户及应用(41)--基于微信开放平台的扫码登录处理>介绍了基于微信开放平台接口实现的微信扫码直接登录的过程.本篇介绍对扫码登录的一些改进和处理,以便更方便应用在实 ...
- C#开发微信门户及应用(41)--基于微信开放平台的扫码登录处理
在现今很多网站里面,都使用了微信开放平台的扫码登录认证处理,这样做相当于把身份认证交给较为权威的第三方进行认证,在应用网站里面可以不需要存储用户的密码了.本篇介绍如何基于微信开放平台的扫码进行网站的登 ...
- 微信开放平台开发——网页微信扫码登录(OAuth2.0)
1.OAuth2.0 OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用. 允许用户提供 ...
- 微信小程序使用场景延伸:扫码登录、扫码支付
微信小程序使用场景延伸:扫码登录.扫码支付 小程序最适合的使用场景有哪些?相比大家能列举出来很多,但这个场景,大家可能多数没想到_^ 笔者团队近期接到了一个PC项目:转转游戏租号PC官网,该项目要求在 ...
- 初涉扫码登录:edusoho实现客户端扫码登录(简版)
一.项目简介及需求 edusoho是一套商业版的在线教育平台,项目本身基于symfony2框架开发,现在有一款自己的APP,要求在不多修改edusoho自身代码的基础上,实现客户端对PC端扫码登录.不 ...
- spring boot高性能实现二维码扫码登录(上)——单服务器版
前言 目前网页的主流登录方式是通过手机扫码二维码登录.我看了网上很多关于扫码登录博客后,发现基本思路大致是:打开网页,生成uuid,然后长连接请求后端并等待登录认证相应结果,而后端每个几百毫秒会循环查 ...
- spring boot高性能实现二维码扫码登录(中)——Redis版
前言 本打算用CountDownLatch来实现,但有个问题我没有考虑,就是当用户APP没有扫二维码的时候,线程会阻塞5分钟,这反而造成性能的下降.好吧,现在回归传统方式:前端ajax每隔1秒或2秒发 ...
- spring boot高性能实现二维码扫码登录(下)——订阅与发布机制版
前言 基于之前两篇(<spring boot高性能实现二维码扫码登录(上)——单服务器版>和<spring boot高性能实现二维码扫码登录(中)——Redis版>)的基础, ...
随机推荐
- Node.Js http服务(websocket)
安装node,下载地址 https://nodejs.org/en/ cmd 中 输入 node -v 安装成功可以查看版本 cmd 中 ctrl - c 可以 结束 和 启动 编辑 js 文本 va ...
- 学习笔记TF056:TensorFlow MNIST,数据集、分类、可视化
MNIST(Mixed National Institute of Standards and Technology)http://yann.lecun.com/exdb/mnist/ ,入门级计算机 ...
- javascript常见问题总结
1.const obj = {a:6}; obj.b=8; obj.a=9;//obj为{a:9,b:8};const定义对象的时候是可以改变内容的. const b = "hello&qu ...
- vue-cli项目在IE下运行钩子函数抛出异常“ReferenceError: “Promise”未定义"”的解决办法
兼容IE是个坑,低版本IE很多都没法跑起来 问题现象:vue-cli项目在IE下运行,会在钩子函数出现 ReferenceError: “Promise”未定义 解决办法: step1:安装最新的we ...
- response响应
郭晨 软件151 1531610114 response1.response常用APIsetStatus:设置响应行当中的状态码setHeader:设置响应头信息getOutputStream:获得字 ...
- webpack学习笔记(六)优化
1 loader 使用include,缩小编译范围: rules: [{ test: /\.js$/, include: path.resolve(__dirname, '../src'), use: ...
- Git 概念
Git 概念 一.Git 工作流程 ~ Workspace:工作区 ~ Index/ Stage:暂存区 ~ Repository:仓库区(或本地仓库) ~ Remote:远程仓库 工作区 进行开发改 ...
- Taro 代码及功能,需要注意的地方
Taro 代码不能使用的写法: 请注意无 AppID 关联下,调用 wx.operateWXData 是受限的, API 的返回是工具的模拟返回
- PHP数组和XML相互转换的函数
//数组转xml function ArrToXml($arr) { if(!is_array($arr) || count($arr) == 0) return ''; $xml = "& ...
- Redis入门的简单使用
Redis是什么? redis是一个开源的,面向键/值对的NOSQL的分布式数据库系统 NOSQL指的是非关系型的数据,简单直白地讲就是在非关系型的数据库中不存在表的概念,而是以键值对的方式, 即一个 ...