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>

效果预览

相关推荐
懒大王爱吃狼29 分钟前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍
逐·風4 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#
Devil枫5 小时前
Vue 3 单元测试与E2E测试
前端·vue.js·单元测试
尚梦6 小时前
uni-app 封装刘海状态栏(适用小程序, h5, 头条小程序)
前端·小程序·uni-app
GIS程序媛—椰子6 小时前
【Vue 全家桶】6、vue-router 路由(更新中)
前端·vue.js
前端青山6 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js
毕业设计制作和分享7 小时前
ssm《数据库系统原理》课程平台的设计与实现+vue
前端·数据库·vue.js·oracle·mybatis
清灵xmf9 小时前
在 Vue 中实现与优化轮询技术
前端·javascript·vue·轮询
大佩梨9 小时前
VUE+Vite之环境文件配置及使用环境变量
前端
GDAL9 小时前
npm入门教程1:npm简介
前端·npm·node.js