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

单设备登录

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

应用场景

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

实现思路

设计数据结构

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

浏览器指纹

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

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

实现代码

nodejs端

js 复制代码
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, //记录ws
                    fingerprint: data.fingerprint //记录指纹
                }
            }
        }
    })
})

浏览器端

html 复制代码
<!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 abf12f62e03d160f7f24144ef1778396

        const ws = new WebSocket('ws://192.168.120.145:3000') //socket本地IP+端口
        ws.addEventListener('open', () => {
            ws.send(JSON.stringify({
                action: 'login', //动作登录
                id: 1, //用户ID
                fingerprint: createBrowserFingerprint() //浏览器指纹
            }))
        })
        ws.addEventListener('message', (message) => {
            const data = JSON.parse(message.data)
            if (data.action === 'logout') {
                alert(data.message) //监听到挤下线操作提示弹框
            }
        })

    </script>
</body>

</html>

预览

相关推荐
山川行几秒前
Python快速闯关8:内置函数
java·开发语言·前端·笔记·python·学习·visual studio
徐小夕34 分钟前
花了一周时间,我们开源了一款PDF编辑SDK,支持在线批注+脱敏
前端·vue.js·github
前端Hardy38 分钟前
Qwik 2.0 Beta 来了:不靠 AI,只靠 Resumability,首屏交互快到离谱
前端·javascript·面试
1-1=01 小时前
ExtJS 快速入门—— 面板 详细版
前端·jquery
前端攻城狮Qwen1 小时前
Service Worker在电子菜单中的实际应用
前端
前端Hardy1 小时前
NW.js v0.109.1 最新稳定版发布:被遗忘的桌面开发神器?启动快 3 倍,内存省 70%!
前端·javascript·vue.js
Kath1 小时前
[归档][2022-05-16]opensumi看码记录
前端
清风徐来QCQ1 小时前
跨域问题(CORS-Cross-Origin Resource Sharing跨域资源共享)
前端
DanCheOo1 小时前
我写了一个 AI 代码质量流水线,一行命令搞定 Review + 修复 + 测试 + 报告
前端·ai编程
yaaakaaang1 小时前
(六)前端,如此简单!--- 三类通讯
前端