参考了下别人说的原理,根据自己的逻辑实现,没有完全按照别人的原理来,所以不一定适用于大家,仅供参考吧!!!

流程如下:

  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实现扫码登录的更多相关文章

  1. Web应用多账号系统设计及微信扫码登录实现

    Web应用多账号系统设计及微信扫码登录实现 1   前言概述 公司对功能测试,性能测试,安全测试等等都做了比较好的自动化后,急需要一个MIS系统来统一管理这些结果及报表. 此MIS系统特点如下: 仅内 ...

  2. C#开发微信门户及应用(45)--微信扫码登录

    在前面随笔<C#开发微信门户及应用(41)--基于微信开放平台的扫码登录处理>介绍了基于微信开放平台接口实现的微信扫码直接登录的过程.本篇介绍对扫码登录的一些改进和处理,以便更方便应用在实 ...

  3. C#开发微信门户及应用(41)--基于微信开放平台的扫码登录处理

    在现今很多网站里面,都使用了微信开放平台的扫码登录认证处理,这样做相当于把身份认证交给较为权威的第三方进行认证,在应用网站里面可以不需要存储用户的密码了.本篇介绍如何基于微信开放平台的扫码进行网站的登 ...

  4. 微信开放平台开发——网页微信扫码登录(OAuth2.0)

    1.OAuth2.0 OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用. 允许用户提供 ...

  5. 微信小程序使用场景延伸:扫码登录、扫码支付

    微信小程序使用场景延伸:扫码登录.扫码支付 小程序最适合的使用场景有哪些?相比大家能列举出来很多,但这个场景,大家可能多数没想到_^ 笔者团队近期接到了一个PC项目:转转游戏租号PC官网,该项目要求在 ...

  6. 初涉扫码登录:edusoho实现客户端扫码登录(简版)

    一.项目简介及需求 edusoho是一套商业版的在线教育平台,项目本身基于symfony2框架开发,现在有一款自己的APP,要求在不多修改edusoho自身代码的基础上,实现客户端对PC端扫码登录.不 ...

  7. spring boot高性能实现二维码扫码登录(上)——单服务器版

    前言 目前网页的主流登录方式是通过手机扫码二维码登录.我看了网上很多关于扫码登录博客后,发现基本思路大致是:打开网页,生成uuid,然后长连接请求后端并等待登录认证相应结果,而后端每个几百毫秒会循环查 ...

  8. spring boot高性能实现二维码扫码登录(中)——Redis版

    前言 本打算用CountDownLatch来实现,但有个问题我没有考虑,就是当用户APP没有扫二维码的时候,线程会阻塞5分钟,这反而造成性能的下降.好吧,现在回归传统方式:前端ajax每隔1秒或2秒发 ...

  9. spring boot高性能实现二维码扫码登录(下)——订阅与发布机制版

     前言 基于之前两篇(<spring boot高性能实现二维码扫码登录(上)——单服务器版>和<spring boot高性能实现二维码扫码登录(中)——Redis版>)的基础, ...

随机推荐

  1. 一道考查request导致的安全性问题的ctf题

    这道题是在看红日安全团队的代码审计系列文章时碰到的,感觉挺有意思的,所以做了下.题目代码如下 //index.php <?php require 'db.inc.php'; function d ...

  2. 企业SQL笔试

    Student(SID, Sname, Sage, Ssex) 学生表        Course(CID, Cname, TID) 课程表        SC(SID, CID, score) 成绩 ...

  3. Python实例之抓取HTML中的数据并保存为TXT

    本实例实现了抓取捧腹网中存储于html中的笑话数据(非JSON数据) 通过浏览器相关工具发现捧腹网笑话页面的数据存储在HTML页面而非json数据中,因此可以直接使用soup.select()方法来抓 ...

  4. 尝试ipad编程 以失败告终

    浏览器选择: safari,iOS内置浏览器,好用,不过有些限制 iPad上的 safari可以把网页保存为pdf,比iphone上的功能强大多了 qq浏览器用来下载文件,之后文件还可以复制到文件管理 ...

  5. ubuntu下Qt链接MySQL: QMYSQL driver not loaded(不用重新编译源码)

    先切换到qt数据库驱动目录即:qt安装目录下的gcc_64/plugins/sqldrivers,然后 ldd libqsqlmysql.so 若libmysqlclient.so.18 not fo ...

  6. 18.16 gcc-3.4.5编译错误及解决方法集锦

    18.16.1 自写BootLoader错误 ERROR : boot.c:: warning: return type of 'main' is not `int' ANSWER : int mai ...

  7. 服务器对接码云webhooks

    服务安装git php代码(外网必须可以访问) <?php //本地路径滚adminasdfdasfasdf $file = "/wwwroot/webhooksLog.txt&quo ...

  8. sdk manager更改国内镜像

    两种方法: 一.参考: https://blog.csdn.net/u010165004/article/details/45227019 打开Android SDK Manager,在Tools下的 ...

  9. CPU的核、进程和线程

    转自https://www.cnblogs.com/-new/p/7234332.html 一.CPU与核心 物理核 物理核数量=cpu数(机子上装的cpu的数量)*每个cpu的核心数 虚拟核 所谓的 ...

  10. Mongodb中的 原子性 隔离性

    读写锁 Mongodb使用读写锁来来控制并发操作: 当进行读操作的时候会加读锁,这个时候其他读操作可以也获得读锁.但是不能或者写锁. 当进行写操作的时候会加写锁,这个时候不能进行其他的读操作和写操作. ...