用户登录基本功能
登录
exports.main = async (event, context) => {
const clientIp = context.ip;
const { captcha } = event;
if (!captcha) {
console.error(`captcha is null, ip = ${clientIp}`);
return null;
}
const user = await db
.collection('user')
.where({
captcha,
captchaExpireTime: _.gt(new Date()),
isDelete: false,
})
.limit(1)
.get()
.then(({ data }) => data[0]);
对用户身份合法性检验
// 用户不存在
if (!user) {
console.log(`user not exists, captcha = ${captcha}`);
return null;
}
// 用户非法
if (!isValidUser(user)) {
console.error(`user is invalid, ip = ${clientIp}, user = ${JSON.stringify(user)}`);
throw new MyError(FORBIDDEN_ERROR_CODE, '禁止访问');
}
若用户合法,则创建登录凭证
// 创建登录凭证
const ticket = app.auth().createTicket(user.unionId, {
refresh: 30 * 24 * 60 * 60 * 1000, // 30 天刷新一次
});
// 存 session 登录态
context.session.userInfo = user;
return {
ticket,
user,
};
限流功能
如果由于人数太多不响应,那就锁定登录功能
const getLock = await app
.callFunction({
name: 'redisService',
data: {
op: 'setnx',
key: `login_${clientIp}`,
value: 1,
expireSeconds: 3,
},
})
.then((tmpRes) => tmpRes.result);
if (!getLock) {
console.error(`cannot getLock, ip = ${clientIp}`);
return FORBIDDEN_CODE;
}
登出
exports.main = async (event, context) => {
// 清除登录态
context.session.userInfo = undefined;
return true;
};
封号或者解封用户
此功能仅管理员可以操作,对于一些用户发表不当言论或者违规操作,管理员可以审核后将其加入黑名单中,用户的账号将会被封禁;当封禁到期,管理员可以移除用户账号,用户即可正常登录。
exports.main = async (event, context) => {
const { userId } = event;
if (!userId) {
return false;
}
// 获取当前登录用户
const currentUser = await getLoginUser(context);
// 仅管理员可操作
if (!isAdminUser(currentUser)) {
throw new MyError(FORBIDDEN_ERROR_CODE, '禁止访问');
}
const user = await db
.collection('user')
.where({
_id: userId,
isDelete: false,
})
.limit(1)
.get()
.then(({ data }) => data[0]);
if (!user) {
return false;
}
const updateData = {
authority: user.authority?.includes('ban') ? 'user' : 'ban',
_updateTime: new Date(),
};
// 更新
const result = await db.collection('user').doc(user._id).update(updateData);
console.log(`updateUser data = ${JSON.stringify(updateData)}`);
return {
code: 200,
data: result,
};
};
用户积分机制
更新用户积分,用户通过优质评论可以获得一定积分,用户下载他人得资源,管理员负责发放积分。
exports.main = async (event, context) => {
const { userId, score, reason = -1, detail } = event;
// 请求参数校验
if (!userId || !score || reason < 0) {
return false;
}
// 封装数据
const data = {
userId,
score,
reason,
detail,
_createTime: new Date(),
_updateTime: new Date(),
isDelete: false,
};
const transaction = await db.startTransaction();
let res;
try {
// 插入用户积分记录
res = await transaction
.collection('userScore')
.add(data)
.then((res) => {
console.log(`addUserScore succeed, id = ${res.id}`);
return true;
})
.catch((e) => {
console.error('addUserScore error', e);
throw e;
});
// 更新用户积分
res = await transaction
.collection('user')
.where({
_id: userId,
isDelete: false,
})
.update({
score: _.inc(score),
_updateTime: new Date(),
})
.then((res) => {
console.log('updateUserScore succeed', res);
return true;
})
.catch((e) => {
console.error('updateUserScore error', e);
throw e;
});
await transaction.commit();
return res;
} catch (e) {
await transaction.rollback();
console.error('未知错误!', e);
return false;
}
};