hn-hlw-service/auth/index.js

369 lines
8.9 KiB
JavaScript
Raw Normal View History

2026-07-27 11:28:33 +08:00
const jwtUtils = require("../utils/jwt-utils");
const logger = require("../utils/logger");
/**
* 认证模块
* 处理用户登录token 刷新等功能
*/
/**
* 用户登录
* @param {Object} params - 登录参数 { username, password, corpId }
* @param {Object} db - 数据库实例
* @returns {Object} 登录结果
*/
async function login(params, db) {
const { username, password, corpId } = params;
if (!username || !password) {
return {
success: false,
message: "用户名和密码不能为空",
};
}
// 查询用户信息
const user = await db.collection("corp-member").findOne(
{ corpId, mobile: username } // 查询条件
);
if (!user) {
logger.warn(`登录失败: 用户不存在 - ${username}`);
return {
success: false,
message: "用户名或密码错误",
};
}
// 验证密码(这里假设密码已加密,实际应该使用 bcrypt 等加密算法)
if (user.password !== password) {
logger.warn(`登录失败: 密码错误 - ${username}`);
return {
success: false,
message: "用户名或密码错误",
};
}
// 检查用户状态
if (user.status === "disabled") {
return {
success: false,
message: "账号已被禁用",
};
}
// 生成 token
const tokens = jwtUtils.generateTokens({
userId: user._id.toString(),
username: user.username,
corpId: user.corpId,
role: user.role || "user",
});
// 更新最后登录时间
await usersCollection.updateOne(
{ _id: user._id },
{
$set: {
lastLoginTime: new Date(),
lastLoginIp: params.ip || "",
},
}
);
logger.info(`用户登录成功: ${username}`);
return {
success: true,
message: "登录成功",
data: {
accessToken: tokens.accessToken,
refreshToken: tokens.refreshToken,
expiresIn: tokens.expiresIn,
tokenType: "Bearer",
userInfo: {
userId: user._id.toString(),
username: user.username,
corpId: user.corpId,
role: user.role || "user",
nickname: user.nickname || user.username,
},
},
};
}
/**
* 刷新 token
* @param {Object} params - 刷新参数 { refreshToken }
* @returns {Object} 刷新结果
*/
async function refreshToken(params) {
const { refreshToken } = params;
if (!refreshToken) {
return {
success: false,
message: "刷新令牌不能为空",
};
}
// 验证并生成新的访问令牌
const result = jwtUtils.refreshAccessToken(refreshToken);
logger.info("Token 刷新成功");
return {
success: true,
message: "Token 刷新成功",
data: {
accessToken: result.accessToken,
expiresIn: result.expiresIn,
tokenType: "Bearer",
},
};
}
/**
* 退出登录
* @param {Object} params - 参数
* @param {Object} user - 当前用户信息来自 JWT
* @returns {Object} 退出结果
*/
async function logout(params, user) {
// 可以在这里实现 token 黑名单机制
// 将当前 token 加入黑名单,使其失效
logger.info(`用户退出登录: ${user.username}`);
return {
success: true,
message: "退出成功",
};
}
/**
* 小程序授权登录支付宝/微信
* @param {Object} params - 登录参数 { authCode, platform, corpId }
* @param {Object} db - 数据库实例
* @returns {Object} 登录结果
*/
async function miniProgramLogin(params, db) {
const { authCode, platform = "alipay", corpId } = params;
if (!authCode) {
return {
success: false,
message: "授权码不能为空",
};
}
try {
// 这里需要调用支付宝/微信的接口获取用户信息
// 由于没有具体的获取用户信息的逻辑,我们假设通过 authCode 可以获取到 userId
// 实际项目中,应该调用对应平台的 API 来验证 authCode 并获取用户信息
// 临时方案:使用 authCode 作为用户标识
// 在实际应用中,需要调用支付宝 API: alipay.system.oauth.token
const userId = authCode; // 这里应该是从支付宝返回的真实 userId
// 查询或创建小程序用户
const usersCollection = db.collection("miniapp_users");
let user = await usersCollection.findOne({
userId,
platform,
...(corpId && { corpId }),
});
if (!user) {
// 首次登录,创建用户记录
const newUser = {
userId,
platform,
corpId: corpId || "",
role: "customer",
status: "active",
createTime: new Date(),
lastLoginTime: new Date(),
lastLoginIp: params.ip || "",
};
const result = await usersCollection.insertOne(newUser);
user = { _id: result.insertedId, ...newUser };
logger.info(`小程序新用户注册: ${userId}`);
} else {
// 更新最后登录时间
await usersCollection.updateOne(
{ _id: user._id },
{
$set: {
lastLoginTime: new Date(),
lastLoginIp: params.ip || "",
},
}
);
logger.info(`小程序用户登录: ${userId}`);
}
// 检查用户状态
if (user.status === "disabled") {
return {
success: false,
message: "账号已被禁用",
};
}
// 生成 JWT token
const tokens = jwtUtils.generateTokens({
userId: user._id.toString(),
miniappUserId: user.userId,
platform: user.platform,
corpId: user.corpId,
role: user.role || "customer",
});
return {
success: true,
message: "登录成功",
data: {
accessToken: tokens.accessToken,
refreshToken: tokens.refreshToken,
expiresIn: tokens.expiresIn,
tokenType: "Bearer",
userInfo: {
userId: user._id.toString(),
miniappUserId: user.userId,
platform: user.platform,
corpId: user.corpId,
role: user.role || "customer",
},
},
};
} catch (error) {
logger.error("小程序登录失败:", error);
return {
success: false,
message: "登录失败: " + error.message,
};
}
}
/**
* 获取当前用户信息
* @param {Object} user - 当前用户信息来自 JWT
* @param {Object} db - 数据库实例
* @returns {Object} 用户信息
*/
async function getCurrentUser(user, db) {
// 判断是小程序用户还是普通用户
if (user.miniappUserId) {
// 小程序用户
const usersCollection = db.collection("miniapp_users");
const userInfo = await usersCollection.findOne({
_id: require("mongodb").ObjectId.createFromHexString(user.userId),
});
if (!userInfo) {
return {
success: false,
message: "用户不存在",
};
}
return {
success: true,
data: {
userId: userInfo._id.toString(),
miniappUserId: userInfo.userId,
platform: userInfo.platform,
corpId: userInfo.corpId,
role: userInfo.role || "customer",
status: userInfo.status,
createTime: userInfo.createTime,
lastLoginTime: userInfo.lastLoginTime,
},
};
} else {
// 普通用户
const usersCollection = db.collection("users");
const userInfo = await usersCollection.findOne(
{ _id: require("mongodb").ObjectId.createFromHexString(user.userId) },
{ projection: { password: 0 } } // 不返回密码
);
if (!userInfo) {
return {
success: false,
message: "用户不存在",
};
}
return {
success: true,
data: {
userId: userInfo._id.toString(),
username: userInfo.username,
corpId: userInfo.corpId,
role: userInfo.role || "user",
nickname: userInfo.nickname || userInfo.username,
email: userInfo.email,
phone: userInfo.phone,
avatar: userInfo.avatar,
status: userInfo.status,
createTime: userInfo.createTime,
lastLoginTime: userInfo.lastLoginTime,
},
};
}
}
/**
* 主路由处理函数
* @param {Object} params - 请求参数
* @param {Object} db - 数据库实例
* @param {Object} user - 当前用户信息可选
* @returns {Object} 处理结果
*/
async function main(params, db, user) {
const { type } = params;
switch (type) {
case "login":
return await login(params, db);
case "miniProgramLogin":
return await miniProgramLogin(params, db);
case "refreshToken":
return await refreshToken(params);
case "logout":
if (!user) {
return { success: false, message: "未登录" };
}
return await logout(params, user);
case "getCurrentUser":
if (!user) {
return { success: false, message: "未登录" };
}
return await getCurrentUser(user, db);
default:
return {
success: false,
message: "未知的操作类型",
};
}
}
module.exports = {
main,
login,
miniProgramLogin,
refreshToken,
logout,
getCurrentUser,
};