测试版本:

python 3.8

djnago 3.2

channels 3.0

需求

在使用channels 建立websocket连接的时候,需要验证客户端的token,并保存一些关键信息

实现原理

使用自定义的中间件进行对token的验证,当然,前端需要把 token放在 headers里

实现步骤

1.创建一个中间件,用来验证token

项目目录下,新建一个 middleware 目录,内部创建一个 my_middleware.py 文件

# middleware/my_middleware.py
# 这是一个无需在settings中注册的中间件
import jwt


class WsTokenVerify:
   """
      websocket 使用的 token解析中间件
  """

   def __init__(self, app):
       # Store the ASGI application we were passed
       self.app = app

   async def __call__(self, scope, receive, send):
       headers = scope['headers']
       # headers 里面是一个个的元组类似于[(b'User-Agent',b'XXXX'),(b'token',b'XXXXX'),……]
       # 从headers中取出token
       for k, v in headers:
           if k.decode() == 'token':
               token = v.decode()
               break
       # 解析 token
       try:
           jwt_dict = jwt.decode(token, key=settings.TOKEN_KEY)
       except Exception as e:
           # 解析失败,则不做任何处理,直接交给视图函数,视图函数会尝试从scope中取出关键信息,失败则会断开websocket连接
           return await self.app(scope, receive, send)
       # 将客户端的唯一身份标识(关键信息)加入scope
       scope['uid'] = jwt_dict['uid']
       scope['nickname'] = jwt_dict['nickname']
       scope['group_name'] = jwt_dict['group_name']
       return await self.app(scope, receive, send)

2.然后改写: 项目目录/项目同名目录/asgi.py文件

import os

from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack   # django 自带用户身份认证
from middleware.my_middleware import WsTokenVerify  # 自己写的用户身份认证
from gps.urls import websocket_urlpatterns # 自定义的路由

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'qixing_app.settings')

django_application = get_asgi_application()

application = ProtocolTypeRouter({
   "http": get_asgi_application(),
   # 这里需要更改官网示例,将AuthMiddlewareStack改为我们刚才自定义的中间件
   "websocket": WsTokenVerify(URLRouter(websocket_urlpatterns))
})

3.编写视图函数(建立连接部分)

class Connect(AsyncWebsocketConsumer):
   async def connect(self):
       try:
           self.uid = self.scope['uid']
           self.nickname = self.scope['nickname']
           self.room_group_name = f"channel_{self.scope['group_name']}"
       except Exception as e:
           # 关键信息获取失败,则断开连接
           print("拒绝连接", e)
           await self.close()
       else:
           # Join room group
           await self.channel_layer.group_add(self.room_group_name, self.channel_name)
           print('建立连接')
           await self.accept()

django-channels自定义中间件验证token的方法的更多相关文章

  1. django实现自定义登陆验证

    django实现自定义登陆验证 自定义装饰器函数和类 from utils.http import HttpResponseUnauthorized from django.views import ...

  2. django系列8.1--django的中间件01 自定义中间件的5个方法

    一.Django中的中间件 Django中间件定义: Middleware is a framework of hooks into Django's request/response process ...

  3. Django 之 自定义中间件

    环境:django:1.10    python: 2.7 简介 中间件是一个轻量级.底层的插件系统,可以介入 django 的请求和响应处理过程,修改 django 的输入和输出. 在 django ...

  4. 什么是django中间件?(七个中间件-自定义中间件)

    目录 一:django中间件 1.什么是django中间件 2.django请求生命周期流程图 二:django自带七个中间件 1.研究django中间件代码规律 2.django支持程序员自定义中间 ...

  5. Django之Middleware中间件方法使用

    自定义中间件五个方法(部分方法)实例 自定义中间件项目: 模板Templates login.html {% load static %} <!DOCTYPE html> <html ...

  6. Django之组件--中间件

    中间件 中间件是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出.因为改变的是全局,所以需要谨慎实用,用不好会影响到性能 自定义中间 ...

  7. Django(5) session登录注销、csrf及中间件自定义、django Form表单验证(非常好用)

    一.Django中默认支持Session,其内部提供了5种类型的Session供开发者使用: 数据库(默认) 缓存 文件 缓存+数据库 加密cookie 1.数据库Session 1 2 3 4 5 ...

  8. (28)django的中间件(自定义中间件和防范跨站请求伪造攻击)-重要的概念

    Django中间件和中间件不是同一种东西 什么是中间件:中间件是一个很大的概念,只要程序和程序之间还有一层程序,用来处理两个程序的整个交互过程的请求.数据等等就叫中间件 Django中间件:是介于re ...

  9. {Django基础九之中间件} 一 前戏 二 中间件介绍 三 自定义中间件 四 中间件的执行流程 五 中间件版登陆认证

    Django基础九之中间件 本节目录 一 前戏 二 中间件介绍 三 自定义中间件 四 中间件的执行流程 五 中间件版登陆认证 六 xxx 七 xxx 八 xxx 一 前戏 我们在前面的课程中已经学会了 ...

  10. asp.net core 3.1 自定义中间件实现jwt token认证

    asp.net core 3.1 自定义中间件实现jwt token认证 话不多讲,也不知道咋讲!直接上代码 认证信息承载对象[user] /// <summary> /// 认证用户信息 ...

随机推荐

  1. MySQL - [18] mysql中关于cascade的用法

    drop database语句用于删除数据库.但如果想要删除一个数据库并且还要删除所有依赖于该数据库的存储过程.函数等,可以使用cascade关键字.drop database test cascad ...

  2. Ansible - [10] Vault(加密&解密)

    加密文件 Ansible 有时需要访问一些敏感数据,如密码.Key等 使用ansible-vault可以加密和解密数据 # 创建测试文件 [root@control ansible]# echo 12 ...

  3. Scala样例类及底层实现伴生对象

    package com.wyh.day01 /** * 样例类的使用 * 1.使用case修饰类 * 2.不需要写构造方法,getter,setter方法,toString方法 * 3.直接通过对象名 ...

  4. CATIA许可证破解方法(CMD版)

    <<< catia的DS License Server Administration后不会自动弹出GUI界面,就需要使用CMD来破解安装许可证. <<< 1. ca ...

  5. 【练习回顾】DS前三次作业

    第一次作业 T2.基本计算器 使用了数组栈--数字栈和符号栈 T5.全排列输出(permutation) 使用了标准写法--字典序算法 void reverse(int left,int right) ...

  6. rust学习笔记(9)

    属性 属性是应用于某些模块.crate 或项的元数据(metadata). 可见性 分为整个crate可见和,使用#![] 例子 一个简单的例子,运行程序中存在未被使用的代码 #[allow(dead ...

  7. 使用makefile帮助GO项目开发

    使用makefile可以快捷管理和构建自己的go项目, 适用于linux远程开发等环境. 提供一个基础的makefile供开发使用. 大部分是针对常用指令的二次封装 Makefile 先展示文件内容, ...

  8. Redis 原理 - Hash

    Hash 数据结构 使用 ziplist 当同时满足下面两个条件时,使用 ziplist 存储数据 元素个数少于512个 (hash-max-ziplist-entries: 512) 每个元素长度小 ...

  9. CMake简单学习

    CMake 说明 cmake的定义是什么 ?-----高级编译配置工具 当多个人用不同的语言或者编译器开发一个项目,最终要输出一个可执行文件或者共享库(dll,so等等)这时候神器就出现了-----C ...

  10. 【Linux】2.1 Linux入门

    Linux入门 1. Linux介绍 Linux 是一款免费,开源,安全,高效,稳定,处理高斌发很强悍的操作系统 Linux创始人--linux(林纳斯) Linux主要发行版本 2. Unix与Li ...