Nodejs 第六十五章(SDL单设备登录)

单设备登录

SDL(Single Device Login)是一种单设备登录的机制,它允许用户在同一时间只能在一个设备上登录,当用户在其他设备上登录时,之前登录的设备会被挤下线。

应用场景

  1. 视频影音,防止一个账号共享,防止一些账号贩子
  2. 社交媒体平台:社交媒体平台通常有多种安全措施来保护用户账户,其中之一就是单设备登录。这样可以防止他人在未经授权的情况下访问用户的账户,并保护用户的个人信息和隐私
  3. 对于在线购物和电子支付平台,用户的支付信息和订单详情是敏感的。通过单设备登录,可以在用户进行支付操作时增加额外的安全层级,确保只有授权设备可以进行支付操作
  4. 对于电子邮箱和通讯应用,用户的个人和机密信息都存储在其中。通过单设备登录机制,可以确保用户的电子邮箱或通讯应用只能在一个设备上登录,避免账户被他人恶意使用

实现思路

设计数据结构
{id:{socket:ws实例fingerprint:浏览器指纹}
}
  1. 第一次登录的时候记录用户id,并且记录socket信息,和浏览器指纹
  2. 当有别的设备登录的时候发现之前已经连接过了,便使用旧的socket发送下线通知,并且关闭旧的socket,更新socket替换成当前新设备的ws连接
浏览器指纹

指纹技术有很多种,这里采用canvas指纹技术

网站将这些颜色数值传递给一个算法,算法会对这些数据进行复杂的计算,生成一个唯一的标识。由于用户使用的操作系统、浏览器、GPU、驱动程序会有差异,在绘制图形的时候会产生差异,这些细微的差异也就导致了生成的标识(哈希值)不一样。因此,每一个用户都可以生成一个唯一的Canvas指纹

实现代码

nodejs端

import express from 'express'
import { WebSocketServer } from 'ws'
import cors from 'cors'
const app = express()
app.use(cors())
app.use(express.json())
//存放数据结构
const connection = {}const server = app.listen(3000)
const wss = new WebSocketServer({ server })wss.on('connection', (ws) => {ws.on('message', (message) => {const data = JSON.parse(message)if (data.action === 'login') {if (connection[data.id] && connection[data.id].fingerprint) {console.log('账号在别处登录')//提示旧设备connection[data.id].socket.send(JSON.stringify({action:'logout',message:`你于${new Date().toLocaleString()}账号在别处登录` }))connection[data.id].socket.close() //断开旧设备连接connection[data.id].socket = ws //更新ws} else {console.log('首次登录')connection[data.id] = {socket: ws, //记录wsfingerprint: data.fingerprint //记录指纹}}}})
})

浏览器端

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><h1>SDL</h1><script src="./md5.js"></script><script>//浏览器指纹const createBrowserFingerprint = () => {const canvas = document.createElement('canvas')const ctx = canvas.getContext('2d')ctx.fillStyle = 'red'ctx.fillRect(0, 0, 1, 1)return md5(canvas.toDataURL())}//谷歌abf12f62e03d160f7f24144ef1778396//火狐80bea69bfc7cad5832d12e41714cf677//Edge abf12f62e03d160f7f24144ef1778396const ws = new WebSocket('ws://192.168.120.145:3000') //socket本地IP+端口ws.addEventListener('open', () => {ws.send(JSON.stringify({action: 'login', //动作登录id: 1, //用户IDfingerprint: createBrowserFingerprint() //浏览器指纹}))})ws.addEventListener('message', (message) => {const data = JSON.parse(message.data)if (data.action === 'logout') {alert(data.message) //监听到挤下线操作提示弹框}})</script>
</body></html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/313.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于项目中加入线程池,导致JVM性能急剧下降的问题

在项目中&#xff0c;为了提高新系统服务的并发处理能力&#xff0c;我在项目中加入了线程池。 由于原来的项目是单线程的一个服务&#xff0c;或者说是一个少线程的服务. 所以公司前辈&#xff0c;将jvm的TLAB 参数配置进行关闭了。 TLAB&#xff08;Thread Local Allocation …

计算机网络 -- 网络编程基础

一 学习准备 1.1 IP地址 在 前文中我们提到过: IP 是全球网络的基础&#xff0c;使用 IP 地址来标识公网环境下主机的唯一性&#xff0c;我们可以根据 目的IP地址 进行跨路由器的远端通信。 但是我们也提到了&#xff0c;通过 IP 地址&#xff0c;只能寻找到目标主机&#xff…

视频质量度量VQM算法详细介绍

视频质量评价 视频质量评价(Video Quality Assessment,VQA)是指通过主观、客观的方式对视频图像的内容、画质等,进行感知、衡量与评价。 ITU definations subjective assessment: the determination of the quality or impairment of programme-like pictures presented…

MASA Framework-原理分析(6)

MASA Framework的原理分析主要涉及到其核心组件、架构设计和运行机制等多个方面。以下是对MASA Framework原理的深入解析&#xff1a; 1. 核心组件与功能 MASA Framework的核心组件包括服务容器、数据存储、消息队列以及监控和管理工具等。这些组件共同协作&#xff0c;为开发…

桌面应用框架概论

目录 桌面应用框架概论 1.介绍 2.优缺点 3.总结 桌面应用框架概论 1.介绍 桌面应用框架种类繁多,以下是一些主要的框架: Electron:这是一个用于创建跨平台桌面应用的开源框架。它允许开发者使用Web技术(HTML、CSS和JavaScript)来构建桌面应用程序,使得桌面应用的开…

字符串的一些有趣案例

文章目录 简介删除文本中的括号和其中的文本 简介 分享python 字符串操作的一些有趣的案例&#xff1a; 正则表达式format … 删除文本中的括号和其中的文本 存在中英文括号混用&#xff0c;故要考虑到所有可能到情况 import re def remove_all_parentheses(text): # 正…

MongoDB聚合运算符:$replaceOne

MongoDB聚合运算符&#xff1a;$replaceOne 文章目录 MongoDB聚合运算符&#xff1a;$replaceOne语法参数字段说明 使用$replaceOne 与 Null$replaceOne 和排序规则$replaceOne 和 Unicode 规范化 举例 $replaceOne聚合运算在输入的字符串中搜索目标字符串&#xff0c;并使用指…

【代码随想录】【动态规划】day48:打家劫舍

打家劫舍1 def rob(self, nums):""":type nums: List[int]:rtype: int"""# 分为两个情况&#xff0c;偷还是不偷&#xff0c;# dp[i]为考虑到第i个房间时的最大值if len(nums) 0: # 如果没有房屋&#xff0c;返回0return 0if len(nums) 1: #…

【 书生·浦语大模型实战营】作业(五):LMDeploy 量化部署

【 书生浦语大模型实战营】作业&#xff08;五&#xff09;&#xff1a;LMDeploy 量化部署 &#x1f389;AI学习星球推荐&#xff1a; GoAI的学习社区 知识星球是一个致力于提供《机器学习 | 深度学习 | CV | NLP | 大模型 | 多模态 | AIGC 》各个最新AI方向综述、论文等成体系…

Linux debian gdb dump

1.开发背景 记录 debian 下应用程序崩溃调试方法 2.开发需求 程序越界可以定位到越界的位置附近 3.开发环境 debian 操作系统&#xff0c;如果不支持需要查看是否存在对应的可执行文件 4.实现步骤 4.1 设置 dump 输出大小 ulimit -c unlimited # 设置输出大小 生成core 文…

【QT+OpenCV】车牌号检测 学习记录 遇到的问题

【QTOpenCV】车牌号检测 学习记录 首先在QT里面配置好OpenCV .pro文件中加入&#xff1a; INCLUDEPATH G:/opencv/build/include LIBS -L"G:/opencv/build/x64/vc14/lib"\-lopencv_core \-lopencv_imgproc \-lopencv_highgui \-lopencv_ml \-lopencv_video \-lo.c…

Linux下SPI设备驱动实验:使用内核提供的读写SPI设备中的数据的函数

一. 简介 前面文章的学习&#xff0c;已经实现了 读写SPI设备中数据的功能。文章如下&#xff1a; Linux下SPI设备驱动实验&#xff1a;验证读写SPI设备中数据的函数功能-CSDN博客 本文来使用内核提供的读写SPI设备中的数据的API函数&#xff0c;来实现读写SPI设备中数据。 …

JSON文件初识

JSON&#xff08;JavaScript Object Notation&#xff09;是一种用于存储和交换数据的轻量级数据格式。它独立于任何编程语言&#xff0c;因此可以在各种语言环境中使用&#xff0c;包括网页、服务器、应用程序等。JSON的简洁性、可读性以及易于解析的特性&#xff0c;使其在网…

HTML5+JavaScript实现本地视频/音频播放器

HTML5JavaScript实现本地视频/音频播放器 HTML5 提供了本地视频和音频播放器的支持&#xff0c;通过 <video> 和 <audio> 标签&#xff0c;这些标签支持多种媒体格式&#xff0c;并且可以通过 JavaScript 进行控制&#xff0c;实现功能比较完整的本地视频音频播放器…

MySQL 8.0 新特性之 Clone Plugin

个人感觉&#xff0c;主要还是为 Group Replication 服务。在 Group Replication 中&#xff0c;如果要添加一个新的节点&#xff0c;这个节点差异数据的补齐是通过分布式恢复&#xff08; Distributed Recovery &#xff09;来实现的。 在 MySQL 8.0.17 之前&#xff0c;只支…

【数据结构】队列(链表模拟队列)

学习本章节必须具备 单链表的前置知识&#xff0c; 建议提前学习&#xff1a;点击链接学习&#xff1a;单链表各种功能函数 细节 详解 本章节是学习用 单链表模拟队列 队列&#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff…

javase基础汇总学习

目录 背景步骤宏观微观理论基础用法面向对象数据类型基础语法&#xff08;关于方法&#xff09;try&#xff08;正常的逻辑代码&#xff09;catch&#xff08;这个和异常有关系&#xff09;finally&#xff08;经典面试题&#xff09; 高阶使用序列化泛型注解反射 总结 背景 后…

大型网站系统架构演化实例_3.使用服务集群改善网站并发处理能力

1.使用服务集群改善网站并发处理能力 使用集群是网站解决高并发、海量数据问题的常用手段。当一台服务器的处理能力、存储空间不足时&#xff0c;不要企图去更换更强大的服务器&#xff0c;对大型网站而言&#xff0c;不管多么强大的服务器&#xff0c;对大型网站而言&…

go interface stuct结构练习报错,结构体定义与main函数位置,结构体变量后加逗号“,”

import "fmt"func main() {//var x interface{} func(x int)string{// return fmt.Sprintf("d:%d",x)//}////switch v:x.(type) { // 局部变量v是类型转换后的结果//case nil:// println("nil")//case*int:// println(*v)//case func…

Jenkins 的构建时执行时间问题

我们希望我的项目能够在特定的时间自动执行&#xff0c;我们需要设定一个定时任务。 Jenkins 的定时任务是通过 Cron 任务来实现的&#xff0c;但是由有点不一样。 H/2 * * * * 比如说上面的设置就是每 2 分钟执行一次。 希望每分钟执行一次 Jenkins 的每分钟执行一次的设置…