Nodejs 第六十六章(SCL扫码登录)

扫码登录

SCL (Scan Code Login) 是一种扫码登录的技术,它允许用户通过扫描二维码来进行登录操作。这种登录方式在许多应用和网站中得到广泛应用,因为它简单、方便且安全。

SCL 扫码登录的优点包括:

  1. 方便快捷:用户只需打开扫码应用程序并扫描二维码即可完成登录,无需手动输入用户名和密码。
  2. 安全性高:扫码登录采用了加密技术,用户的登录信息在传输过程中得到保护,降低了密码被盗取或泄露的风险。
  3. 避免键盘记录:由于用户无需在登录过程中输入敏感信息,如用户名和密码,因此不会受到键盘记录软件的威胁。
  4. 适用性广泛:SCL 扫码登录可以与不同的应用和网站集成,提供统一的登录方式,使用户无需记住多个账户的用户名和密码。

实现流程

安装的依赖

  1. express 提供接口服务
  2. jsonwebtoken 生成token
  3. qrcode 生成二维码

流程图

大体逻辑

js 复制代码
  const status = {
    0: '未授权',
    1: '已授权',
    2: '超时'
}
  1. 需要一个页面调用接口获取qrcode也就是二维码去展示,然后顺便展示一下状态,默认0 未授权
  2. 在这个页面轮询接口检查状态是否是已授权,如果是已授权或者超时就停止轮询。
  3. 扫码之后会打开授权页面,在授权页面点击确认按钮进行授权分配token

代码实现

目录结构

public

  1. mandate.html 授权页面
  2. qrcode.html 二维码页面

index.js nodejs逻辑代码

index.js

js 复制代码
import express from 'express'
import qrcode from 'qrcode'
import jwt from 'jsonwebtoken'

let user = {

}
let userId = 1 //模拟一个用户
const app = express()
app.use(express.json())
app.use('/static', express.static('public')) //初始化静态目录
//初始化数据结构 记录用户和创建二维码的时间
//并且生成二维码的时候使用的是授权的那个页面并且把用户id带过去
app.get('/qrcode', async (req, res) => {
    user[userId] = {
        token: null,
        time: Date.now()
    }
    const code = await qrcode.toDataURL(`http://192.168.120.145:3000/static/mandate.html?userId=${userId}`)
    res.json({
        code,
        userId
    })
})
//授权确认接口 陈功授权之后生成token
app.post('/login/:userId', (req, res) => {
    const token = jwt.sign(req.params.userId, 'secret')
    user[req.params.userId].token = token
    user[req.params.userId].time = Date.now()
    res.json({
        token
    })
})
//检查接口 这个接口要被轮询调用检查状态,0未授权 1已授权 2超时
app.get('/check/:userId', (req, res) => {
    //判断超时时间
    if (Date.now() - user[userId].time > 1000 * 60 * 1) {
        return res.json({
            status: 2
        })
    }
    //如果有token那就是验证成功
    else if (user[1].token) {
        return res.json({
            status: 1
        })
    } else {
        return res.json({
            status: 0
        })
    }
})

app.listen(3000, () => {
    console.log('http://localhost:3000')
})

qrcode.html

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>
    <img id="qrcode" src="" alt="">
    <div id="status-div"></div>
    <script>
        const status = {
            0: '未授权',
            1: '已授权',
            2: '超时'
        }
        const qrcode = document.getElementById('qrcode')
        const statusDiv = document.getElementById('status-div')
        let userId = null
        statusDiv.innerText = status[0]
        fetch('/qrcode').then(res => res.json()).then(res => {
            qrcode.src = res.code //获取二维码
            userId = res.userId //获取用户id
            let timer = setInterval(() => {
               //轮询调用检查接口
                fetch(`/check/${userId}`).then(res => res.json()).then(res => {
                    statusDiv.innerText = status[res.status]
                    //如果返回的状态是 超时 或者是已授权 就停止轮训
                    if (res.status != 0) {
                        clearInterval(timer)
                    }
                })
            }, 1000)
        })

    </script>
</body>

</html>

mandate.html

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>
    <div> <button id="btn" style="width: 100%;height: 50px;">同意授权</button></div>
    <div> <button style="width: 100%;height: 50px;margin-top: 20px;">拒绝授权</button></div>
    <script>
        const btn = document.getElementById('btn')
        let userId = location.search.slice(1).split('=')[1]
        btn.onclick = () => {
            //点击授权按钮
            fetch(`/login/${userId}`, {
                method: 'POST',
            }).then(res => res.json()).then(res => {
                alert(`授权成功`)
            }).catch(err => {
                alert(err)
            })
        }
    </script>
</body>

</html>

效果预览

相关推荐
我是真菜37 分钟前
彻底理解js中的深浅拷贝
前端·javascript
江畔柳前堤1 小时前
github实战指南07-CLI 与高级技巧
前端·人工智能·chrome·深度学习·github·caffe·issue
weixin_571667411 小时前
[解决] Node.js 安装后 命令找不到
node.js
kisdiem1 小时前
ReAct:让大模型一边推理,一边行动
前端·react.js·前端框架
西部荒野子1 小时前
JS 如何跑进两个原生世界
前端
RANxy1 小时前
AntV 入门系列第一篇:从零开始的数据可视化之旅
前端
小小小小宇2 小时前
前端 WebRTC 全解析与应用
前端
华玥2 小时前
优化滚动列表,使用虚拟滚动
前端
小小小小宇2 小时前
前端 WebAssembly 全解析与应用
前端
huangdong_2 小时前
京东商品图片视频批量下载与m3u8视频合并技术完整实现方案
大数据·前端·数据库