fix: 云函数鉴权加固与投票数据防护

- follow/cms-vote/cms-articles-like/cms-articles-collect 云对象写操作强制 checkToken,uid 以服务端令牌为准,杜绝客户端伪造身份
- user-info.getIP 仅允许查询本人登录 IP(get_user_info 公开资料保持不变)
- ext-storage-co 上传凭证需登录,删除文件仅限 admin 角色(原为完全裸奔)
- cms-vote/cms-vote-info/user_select_vote 三表 schema 写权限全部关闭(投票读写均走云对象)
- 修复 follow.reFollow 中 total<0 永假导致的逻辑错误
- 各云对象 package.json 补 uni-id-common 依赖声明
- main.js 登录过期跳转修正为实际页面路径 /pages/login/login
This commit is contained in:
2026-09-10 21:31:25 +08:00
parent 3cd8fc247d
commit 50f8a89d51
16 changed files with 83 additions and 37 deletions
+1 -1
View File
@@ -94,7 +94,7 @@ function handleTokenExpired() {
showCancel: false, showCancel: false,
success: () => { success: () => {
uni.removeStorageSync('uni_id_token') uni.removeStorageSync('uni_id_token')
uni.reLaunch({ url: '/pages/login' }) uni.reLaunch({ url: '/pages/login/login' })
} }
}) })
} }
@@ -1,13 +1,18 @@
const db = uniCloud.database(); const db = uniCloud.database();
const _ = db.command; const _ = db.command;
const uniID = require('uni-id-common');
module.exports = { module.exports = {
_before: function () { // 通用预处理器 _before: function () { // 通用预处理器
this.uniID = uniID.createInstance({
context: this.getClientInfo()
});
}, },
async collectArticle(query) { async collectArticle(query) {
let user_id = query.user_id; const payload = await this.uniID.checkToken(this.getUniIdToken());
if (payload.errCode) throw new Error('登录状态失效,请重新登录');
let user_id = payload.uid; // 以服务端令牌为准,忽略客户端传入
let article_id = query.article_id; let article_id = query.article_id;
let datetime = new Date().getTime(); let datetime = new Date().getTime();
const transaction = await db.startTransaction(); const transaction = await db.startTransaction();
@@ -49,7 +54,9 @@ module.exports = {
async recollectArticle(query) { async recollectArticle(query) {
try { try {
let user_id = query.user_id; const payload = await this.uniID.checkToken(this.getUniIdToken());
if (payload.errCode) throw new Error('登录状态失效,请重新登录');
let user_id = payload.uid; // 以服务端令牌为准,忽略客户端传入
let article_id = query.article_id; let article_id = query.article_id;
const reclollectRes = await db.collection('cms-articles-collect') const reclollectRes = await db.collection('cms-articles-collect')
@@ -1,6 +1,8 @@
{ {
"name": "cms-articles-collect", "name": "cms-articles-collect",
"dependencies": {}, "dependencies": {
"uni-id-common": "file:../../../uni_modules/uni-id-common/uniCloud/cloudfunctions/common/uni-id-common"
},
"extensions": { "extensions": {
"uni-cloud-jql": {} "uni-cloud-jql": {}
} }
@@ -1,13 +1,18 @@
const db = uniCloud.database(); const db = uniCloud.database();
const _ = db.command; const _ = db.command;
const uniID = require('uni-id-common');
module.exports = { module.exports = {
_before: function () { _before: function () {
this.uniID = uniID.createInstance({
context: this.getClientInfo()
});
}, },
async likeArticle(query) { async likeArticle(query) {
let user_id = query.user_id; const payload = await this.uniID.checkToken(this.getUniIdToken());
if (payload.errCode) throw new Error('登录状态失效,请重新登录');
let user_id = payload.uid; // 以服务端令牌为准,忽略客户端传入
let article_id = query.article_id; let article_id = query.article_id;
let datetime = new Date().getTime(); let datetime = new Date().getTime();
@@ -50,7 +55,9 @@ module.exports = {
async relikeArticle(query) { async relikeArticle(query) {
try { try {
let user_id = query.user_id; const payload = await this.uniID.checkToken(this.getUniIdToken());
if (payload.errCode) throw new Error('登录状态失效,请重新登录');
let user_id = payload.uid; // 以服务端令牌为准,忽略客户端传入
let article_id = query.article_id; let article_id = query.article_id;
let datetime = new Date().getTime(); let datetime = new Date().getTime();
@@ -1,6 +1,8 @@
{ {
"name": "cms-articles-like", "name": "cms-articles-like",
"dependencies": {}, "dependencies": {
"uni-id-common": "file:../../../uni_modules/uni-id-common/uniCloud/cloudfunctions/common/uni-id-common"
},
"extensions": { "extensions": {
"uni-cloud-jql": {} "uni-cloud-jql": {}
} }
@@ -1,10 +1,13 @@
const { count } = require("console"); const { count } = require("console");
const uniID = require('uni-id-common');
const db = uniCloud.database(); const db = uniCloud.database();
const _ =db.command; const _ =db.command;
module.exports = { module.exports = {
_before: function () { // 通用预处理器 _before: function () { // 通用预处理器
this.uniID = uniID.createInstance({
context: this.getClientInfo()
});
}, },
async getVoteInfo(query) { async getVoteInfo(query) {
try { try {
@@ -42,12 +45,15 @@ module.exports = {
}, },
async add_vote(query) { async add_vote(query) {
try { try {
const payload = await this.uniID.checkToken(this.getUniIdToken());
if (payload.errCode) throw new Error('登录状态失效,请重新登录');
let { let {
vote_id, vote_id,
selectValue, selectValue,
user_id, user_id,
type type
} = query; } = query;
user_id = payload.uid; // 以服务端令牌为准,忽略客户端传入
let t = await db.collection("cms-vote") let t = await db.collection("cms-vote")
.where({ .where({
@@ -1,6 +1,8 @@
{ {
"name": "cms-vote", "name": "cms-vote",
"dependencies": {}, "dependencies": {
"uni-id-common": "file:../../../uni_modules/uni-id-common/uniCloud/cloudfunctions/common/uni-id-common"
},
"extensions": { "extensions": {
"uni-cloud-jql": {} "uni-cloud-jql": {}
} }
@@ -1,4 +1,6 @@
const uniID = require('uni-id-common');
const extStorageManager = uniCloud.getExtStorageManager({ const extStorageManager = uniCloud.getExtStorageManager({
provider: "qiniu", provider: "qiniu",
domain:"qnycdn.mymoyu.top", domain:"qnycdn.mymoyu.top",
@@ -10,7 +12,9 @@ module.exports = {
_before: function() { _before: function() {
}, },
getUploadFileOptions(data = {}) { async getUploadFileOptions(data = {}) {
const { errCode } = await uniID.createInstance({ context: this.getClientInfo() }).checkToken(this.getUniIdToken());
if (errCode) throw new Error('请先登录后再上传文件');
let { let {
cloudPath cloudPath
} = data; } = data;
@@ -48,6 +52,8 @@ module.exports = {
// }, // },
// // 删除文件 // // 删除文件
async deleteFile(data = {}) { async deleteFile(data = {}) {
const { role, errCode } = await uniID.createInstance({ context: this.getClientInfo() }).checkToken(this.getUniIdToken());
if (errCode || !(role || []).includes('admin')) throw new Error('仅管理员可删除文件');
let { let {
fileList fileList
} = data; } = data;
@@ -1,7 +1,9 @@
{ {
"type": "module", "type": "module",
"name": "ext-storage-co", "name": "ext-storage-co",
"dependencies": {}, "dependencies": {
"uni-id-common": "file:../../../uni_modules/uni-id-common/uniCloud/cloudfunctions/common/uni-id-common"
},
"extensions": { "extensions": {
"uni-cloud-ext-storage": {} "uni-cloud-ext-storage": {}
}, },
@@ -1,8 +1,11 @@
const db = uniCloud.database(); const db = uniCloud.database();
const _ = db.command; const _ = db.command;
const uniID = require('uni-id-common');
module.exports = { module.exports = {
_before: function () { // 通用预处理器 _before: function () { // 通用预处理器
this.uniID = uniID.createInstance({
context: this.getClientInfo()
});
}, },
async getIsFollow(query) { async getIsFollow(query) {
try { try {
@@ -35,10 +38,10 @@ module.exports = {
}, },
async follow(query) { async follow(query) {
try { try {
const { const payload = await this.uniID.checkToken(this.getUniIdToken());
uid, if (payload.errCode) throw new Error('登录状态失效,请重新登录');
fid const uid = payload.uid; // 以服务端令牌为准,忽略客户端传入
} = query; const fid = query.fid;
const res = await db.collection("follow").where({ const res = await db.collection("follow").where({
uid: uid, uid: uid,
fid: fid fid: fid
@@ -70,15 +73,15 @@ module.exports = {
}, },
async reFollow(query) { async reFollow(query) {
try { try {
const { const payload = await this.uniID.checkToken(this.getUniIdToken());
uid, if (payload.errCode) throw new Error('登录状态失效,请重新登录');
fid const uid = payload.uid; // 以服务端令牌为准,忽略客户端传入
} = query; const fid = query.fid;
const res = await db.collection("follow").where({ const res = await db.collection("follow").where({
uid: uid, uid: uid,
fid: fid fid: fid
}).count(); }).count();
if (res.total < 0) { if (res.total == 0) {
return { return {
code: 201, code: 201,
msg: "未关注" msg: "未关注"
@@ -1,6 +1,8 @@
{ {
"name": "follow", "name": "follow",
"dependencies": {}, "dependencies": {
"uni-id-common": "file:../../../uni_modules/uni-id-common/uniCloud/cloudfunctions/common/uni-id-common"
},
"extensions": { "extensions": {
"uni-cloud-jql": {} "uni-cloud-jql": {}
} }
@@ -1,6 +1,7 @@
const db = uniCloud.database(); const db = uniCloud.database();
const _ = db.command; const _ = db.command;
const crypto = require('crypto'); const crypto = require('crypto');
const uniID = require('uni-id-common');
let obj = { let obj = {
isValidIP(ip) { isValidIP(ip) {
// ------------------------- IPv4 验证 ------------------------- // ------------------------- IPv4 验证 -------------------------
@@ -134,11 +135,15 @@ let obj = {
} }
module.exports = { module.exports = {
_before: function () { // 通用预处理器 _before: function () { // 通用预处理器
this.uniID = uniID.createInstance({
context: this.getClientInfo()
});
}, },
async getIP(query) { async getIP(query) {
try { try {
let { uid } = query; const payload = await this.uniID.checkToken(this.getUniIdToken());
if (payload.errCode) throw new Error('登录状态失效,请重新登录');
let uid = payload.uid; // 仅允许查询自己的登录 IP
let res = await db.collection("uni-id-users") let res = await db.collection("uni-id-users")
.doc(uid) .doc(uid)
.field({ .field({
@@ -1,6 +1,8 @@
{ {
"name": "user-info", "name": "user-info",
"dependencies": {}, "dependencies": {
"uni-id-common": "file:../../../uni_modules/uni-id-common/uniCloud/cloudfunctions/common/uni-id-common"
},
"extensions": { "extensions": {
"uni-cloud-ext-storage": {} "uni-cloud-ext-storage": {}
} }
@@ -3,9 +3,9 @@
"required": [], "required": [],
"permission": { "permission": {
"read": true, "read": true,
"create": true, "create": false,
"update": true, "update": false,
"delete": true "delete": false
}, },
"properties": { "properties": {
"_id": { "_id": {
@@ -3,9 +3,9 @@
"required": [], "required": [],
"permission": { "permission": {
"read": true, "read": true,
"create": true, "create": false,
"update": true, "update": false,
"delete": true "delete": false
}, },
"properties": { "properties": {
"_id": { "_id": {
@@ -4,9 +4,9 @@
"required": [], "required": [],
"permission": { "permission": {
"read": true, "read": true,
"create": true, "create": false,
"update": true, "update": false,
"delete": true "delete": false
}, },
"properties": { "properties": {
"_id": { "_id": {