Browse Source

✨ feat: 增加统一认证接口

Pchen. 9 months ago
parent
commit
3069f5dbf1
4 changed files with 277 additions and 3 deletions
  1. 113 0
      apis/User/qqLogin/qqLoginStep1.js
  2. 48 0
      apis/User/uniLogin/GetLoginUrl.js
  3. 107 0
      apis/User/uniLogin/Login.js
  4. 9 3
      config.json

+ 113 - 0
apis/User/qqLogin/qqLoginStep1.js

@@ -0,0 +1,113 @@
+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");
+
+class qqLoginStep1 extends API {
+    constructor() {
+        super()
+
+        this.setPath('/User/qqLoginStep1')
+        this.setMethod('POST')
+    }
+
+    async onRequest(req, res) {
+        let { qq, location, deviceInfo } = req.body
+
+        if ([qq, deviceInfo].some(value => value === '' || value === null || value === undefined))
+            return res.json({
+                ...BaseStdResponse.MISSING_PARAMETER
+            })
+
+        if(String(qq).length > 10 || String(qq).length < 5)
+            return res.json({
+                ...BaseStdResponse.ERR,
+                msg: '请输入正确的QQ号'
+            })
+
+        const uniConfig = config.unilogin
+
+        let url = `${uniConfig.url}/connect.php?act=callback&appid=${uniConfig.appid}&appkey=${uniConfig.appkey}&type=${type || 'qq'}&code=${code}`
+        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,
+                }
+            })
+
+            // 增加登录记录
+
+
+        } catch (error) {
+            this.logger.error(`获取用户信息失败!${error.message || 'api接口错误'}`)
+            return res.json({
+                ...BaseStdResponse.ERR,
+                msg: '获取用户信息失败!'
+            })
+        }
+    }
+}
+
+module.exports.qqLoginStep1 = qqLoginStep1

+ 48 - 0
apis/User/uniLogin/GetLoginUrl.js

@@ -0,0 +1,48 @@
+const API = require("../../../lib/API")
+const axios = require('axios')
+const config = require('../../../config.json')
+const { BaseStdResponse } = require("../../../BaseStdResponse");
+
+class GetLoginUrl extends API {
+    constructor() {
+        super();
+
+        this.setPath('/UniLogin/GetLoginUrl')
+        this.setMethod('GET')
+    }
+
+    async onRequest(req, res) {
+        let { type } = req.query
+
+        const uniConfig = config.unilogin
+
+        let url = `${uniConfig.url}/connect.php?act=login&appid=${uniConfig.appid}&appkey=${uniConfig.appkey}&type=${type || 'qq'}&redirect_uri=${uniConfig.return_url}`
+
+        try {
+            const r = await axios.get(url, {
+                proxy: false
+            })
+
+            if (!r || r.data?.code !== 0 || !r.data?.url) {
+                this.logger.error(`获取聚合登录链接失败!${r.data?.msg || 'api接口错误'}`)
+                return res.json({
+                    ...BaseStdResponse.ERR,
+                    msg: '获取聚合登录链接失败!'
+                })
+            }
+
+            res.json({
+                ...BaseStdResponse.OK,
+                data: r.data.url
+            })
+        } catch (error) {
+            this.logger.error(`获取聚合登录链接失败!${error.message || 'api接口错误'}`)
+            return res.json({
+                ...BaseStdResponse.ERR,
+                msg: '获取聚合登录链接失败!'
+            })
+        }
+    }
+}
+
+module.exports.GetLoginUrl = GetLoginUrl;

+ 107 - 0
apis/User/uniLogin/Login.js

@@ -0,0 +1,107 @@
+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");
+
+class Login extends API {
+    constructor() {
+        super()
+
+        this.setPath('/UniLogin/Login')
+        this.setMethod('POST')
+    }
+
+    async onRequest(req, res) {
+        let { type, code } = req.body
+
+        if ([code].some(value => value === '' || value === null || value === undefined))
+            return res.json({
+                ...BaseStdResponse.MISSING_PARAMETER
+            })
+
+        const uniConfig = config.unilogin
+
+        let url = `${uniConfig.url}/connect.php?act=callback&appid=${uniConfig.appid}&appkey=${uniConfig.appkey}&type=${type || 'qq'}&code=${code}`
+        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,
+                }
+            })
+
+            // 增加登录记录
+
+
+        } catch (error) {
+            this.logger.error(`获取用户信息失败!${error.message || 'api接口错误'}`)
+            return res.json({
+                ...BaseStdResponse.ERR,
+                msg: '获取用户信息失败!'
+            })
+        }
+    }
+}
+
+module.exports.Login = Login;

+ 9 - 3
config.json

@@ -2,9 +2,9 @@
     "port": 30003,
     "database": {
         "host": "8.137.37.202",
-        "database": "ic_ctbu",
-        "port": 13306,
-        "user": "root",
+        "database": "ic",
+        "port": 41306,
+        "user": "ic",
         "password": "yx3ud937"
     },
     "redis": {
@@ -29,5 +29,11 @@
         "key": "WfRF4t9wcepCjLs18lUoxRS2HiSF5mHI",
         "return_url": "https://lepao.vite.net.cn/#/store/orderDetail/"
     },
+    "unilogin": {
+        "url": "https://open.losfer.cn",
+        "appid": "1274",
+        "appkey": "e9dd049e0d991b997901957200036b30",
+        "return_url": "https://xxoo365.top/uniLogin/loginSuccess"
+    },
     "server": "CTBU_CLUB 重庆1号服务器"
 }