Browse Source

✨ feat: 增加QQ登录接口

Pchen. 9 months ago
parent
commit
d71217bd03
2 changed files with 136 additions and 87 deletions
  1. 27 87
      apis/User/qqLogin/qqLoginStep1.js
  2. 109 0
      apis/User/qqLogin/qqLoginStep2.js

+ 27 - 87
apis/User/qqLogin/qqLoginStep1.js

@@ -1,113 +1,53 @@
-const API = require("../../../lib/API")
-const axios = require('axios')
-const { v4: uuidv4 } = require('uuid')
-const db = require("../../../plugin/DataBase/db")
-const config = require('../../../config.json')
-const { BaseStdResponse } = require("../../../BaseStdResponse");
+const API = require("../../lib/API")
+const { BaseStdResponse } = require("../../BaseStdResponse")
+const Redis = require('../../plugin/DataBase/Redis')
+const EmailTemplate = require('../../plugin/Email/emailTemplate')
 
 
+// 发送邮箱验证码
 class qqLoginStep1 extends API {
 class qqLoginStep1 extends API {
     constructor() {
     constructor() {
         super()
         super()
 
 
-        this.setPath('/User/qqLoginStep1')
-        this.setMethod('POST')
+        this.setMethod("POST")
+        this.setPath("/User/qqLoginStep1")
     }
     }
 
 
     async onRequest(req, res) {
     async onRequest(req, res) {
-        let { qq, location, deviceInfo } = req.body
+        const { qq } = req.body
 
 
-        if ([qq, deviceInfo].some(value => value === '' || value === null || value === undefined))
+        if ([qq].some(value => value === '' || value === null || value === undefined))
             return res.json({
             return res.json({
                 ...BaseStdResponse.MISSING_PARAMETER
                 ...BaseStdResponse.MISSING_PARAMETER
             })
             })
 
 
-        if(String(qq).length > 10 || String(qq).length < 5)
-            return res.json({
+        if(String(qq).length < 6 || String(qq).length > 10)
+             return res.json({
                 ...BaseStdResponse.ERR,
                 ...BaseStdResponse.ERR,
                 msg: '请输入正确的QQ号'
                 msg: '请输入正确的QQ号'
             })
             })
 
 
-        const uniConfig = config.unilogin
+        const email = `${qq}@qq.com`
+        const code = Math.random().toFixed(6).slice(-6)
 
 
-        let url = `${uniConfig.url}/connect.php?act=callback&appid=${uniConfig.appid}&appkey=${uniConfig.appkey}&type=${type || 'qq'}&code=${code}`
         try {
         try {
-            const r = await axios.get(url, {
-                proxy: false
-            })
-
-            if (!r || r.data?.code !== 0) {
-                this.logger.error(`获取用户信息失败!${r.data?.msg || 'api接口错误'}`)
-                return res.json({
-                    ...BaseStdResponse.ERR,
-                    msg: '获取用户信息失败!'
-                })
-            }
-
-            let { social_uid, nickname, faceimg, ip } = r.data
-            const session = uuidv4()
-            const time = new Date().getTime()
-
-            let selectSql = 'SELECT uuid, permission FROM users WHERE social_uid = ? AND social_type = ?'
-            let selectRows = await db.query(selectSql, [social_uid, type || 'qq'])
-
-            let uuid, username, permission
-
-            // 用户不存在 执行注册操作
-            if (selectRows.length == 0) {
-                uuid = uuidv4()
-                username = `用户${uuid.slice(0, 8)}`
-
-                let regSql = 'INSERT INTO users (uuid, username, session, registTime, social_uid, social_type, nickname, avatar, email) VALUES (?,?,?,?,?,?,?,?,?) '
-                let regRows = await db.query(regSql, [uuid, username, session, time, social_uid, type || 'qq', nickname, faceimg, '未设置'])
-                if (!regRows || regRows.affectedRows !== 1) {
-                    this.logger.error(`聚合登录用户注册失败!数据库错误`)
-                    return res.json({
-                        ...BaseStdResponse.ERR,
-                        msg: '用户注册失败!'
-                    })
-                }
-            }
-
-            else {
-                let updateSql = 'UPDATE users SET session = ?, lastTime = ?, avatar = ?, nickname = ? WHERE social_uid = ? AND login_type = ?'
-                let updateRows = await db.query(updateSql, [session, time, faceimg, nickname, social_uid, type || 'qq'])
-                if (!updateRows || updateRows.affectedRows !== 1) {
-                    this.logger.error(`聚合登录用户登录失败!数据库错误`)
-                    return res.json({
-                        ...BaseStdResponse.ERR,
-                        msg: '用户登录失败!请稍后再试'
-                    })
-                }
-
-                username = selectRows[0].username
-                permission = selectRows[0].permission
-
-            }
-
-            res.json({
-                ...BaseStdResponse.OK,
-                data: {
-                    uuid,
-                    username,
-                    session,
-                    nickname,
-                    type: type || 'qq',
-                    roles: permission || [],
-                    avatar: faceimg,
-                }
+            await Redis.set(`email:${email}`, code, {
+                EX: 600
             })
             })
-
-            // 增加登录记录
-
-
-        } catch (error) {
-            this.logger.error(`获取用户信息失败!${error.message || 'api接口错误'}`)
+        } catch (err) {
+            this.logger.error(`发送邮箱验证码失败!${err.stack}`)
             return res.json({
             return res.json({
-                ...BaseStdResponse.ERR,
-                msg: '获取用户信息失败!'
+                ...BaseStdResponse.SMS_SEND_FAIL,
+                msg: '请检查邮箱格式后再试!'
             })
             })
         }
         }
+
+        res.json({
+            ...BaseStdResponse.OK
+        })
+
+        // 先返回后发送
+        EmailTemplate.checkEmail(email, code)
     }
     }
 }
 }
 
 
-module.exports.qqLoginStep1 = qqLoginStep1
+module.exports.qqLoginStep1 = qqLoginStep1

+ 109 - 0
apis/User/qqLogin/qqLoginStep2.js

@@ -0,0 +1,109 @@
+const API = require("../../../lib/API")
+const { v4: uuidv4 } = require('uuid')
+const Redis = require('../../plugin/DataBase/Redis')
+const db = require("../../../plugin/DataBase/db")
+const { BaseStdResponse } = require("../../../BaseStdResponse");
+
+class qqLoginStep2 extends API {
+    constructor() {
+        super()
+
+        this.setPath('/User/qqLoginStep2')
+        this.setMethod('POST')
+    }
+
+    async onRequest(req, res) {
+        let { qq, code, location, deviceInfo } = req.body
+
+        if ([qq, code].some(value => value === '' || value === null || value === undefined))
+            return res.json({
+                ...BaseStdResponse.MISSING_PARAMETER
+            })
+
+        if (String(qq).length < 6 || String(qq).length > 10)
+            return res.json({
+                ...BaseStdResponse.ERR,
+                msg: '请输入正确的QQ号'
+            })
+
+        const email = `${qq}@qq.com`
+
+        try {
+            const VerifyCode = await Redis.get(`email:${email}`)
+            if (!VerifyCode || VerifyCode != code)
+                return res.json({
+                    ...BaseStdResponse.SMS_CHECK_FAIL,
+                    msg: '验证码输入错误或已过期'
+                })
+        } catch (err) {
+            this.logger.error(`验证验证码失败!${err.stack}`)
+            return res.json({
+                ...BaseStdResponse.DATABASE_ERR,
+                msg: '验证失败!'
+            })
+        }
+
+        const session = uuidv4()
+        const time = new Date().getTime()
+
+        let selectSql = 'SELECT username, permission, avatar FROM users WHERE email = ?'
+        let selectRows = await db.query(selectSql, [email])
+
+        let uuid, username, permission, avatar
+
+        // 用户不存在 执行注册操作
+        if (selectRows.length == 0) {
+            uuid = uuidv4()
+            username = `用户${uuid.slice(0, 8)}`
+            avatar = `https://q1.qlogo.cn/g?b=qq&nk=${qq}&s=640`
+
+            let regSql = 'INSERT INTO users (uuid, username, session, registTime, avatar, email) VALUES (?,?,?,?,?,?) '
+            let regRows = await db.query(regSql, [uuid, username, session, time, avatar, email])
+            if (!regRows || regRows.affectedRows !== 1) {
+                this.logger.error(`用户注册失败!数据库错误`)
+                return res.json({
+                    ...BaseStdResponse.ERR,
+                    msg: '用户注册失败!'
+                })
+            }
+        }
+
+        else {
+            let updateSql = 'UPDATE users SET session = ?, lastTime = ? WHERE email = ?'
+            let updateRows = await db.query(updateSql, [session, time, email])
+            if (!updateRows || updateRows.affectedRows !== 1) {
+                this.logger.error(`用户登录失败!数据库错误`)
+                return res.json({
+                    ...BaseStdResponse.ERR,
+                    msg: '用户登录失败!请稍后再试'
+                })
+            }
+
+            avatar = selectRows[0].avatar
+            username = selectRows[0].username
+            permission = selectRows[0].permission
+        }
+
+        res.json({
+            ...BaseStdResponse.OK,
+            data: {
+                uuid,
+                username,
+                session,
+                roles: permission || [],
+                avatar
+            }
+        })
+
+        // 增加登录记录
+        try {
+            const ip = req.headers['x-forwarded-for']?.split(',')[0].trim() || req.connection.remoteAddress
+            let insertSql = 'INSERT INTO login_history (uuid, time, location, deviceInfo, type, ip)'
+            await db.query(insertSql, [uuid, time, location, deviceInfo, 'qq', ip])
+        } catch (error) {
+            this.logger.error(`写入登录记录失败!${error}`)
+        }
+    }
+}
+
+module.exports.qqLoginStep2 = qqLoginStep2