UNPKG

mm_os

Version:

MM_OS服务端架构,用于快速构建应用程序,支持网站建设、小程序后台、AI应用、物联网(IOT/AIOT)、游戏服务端等多种场景。

201 lines (188 loc) 4.7 kB
/** * Oauth身份验证驱动类 * @class */ class Oauth { static config = { // 是否登录 'sign_in': false, // 要求会员级别 'vip': 0, // 要求管理级别 'gm': 0, // 要求商户级别 'mc': 0, // 要求用户组 'user_group': [], // 要求管理组 'user_admin': [], // 文件路径, 当调用函数不存在时,会先从文件中加载 'main': '' }; /** * 构造函数 * @param {string} config 当前路径 * @class */ constructor(config) { // 配置参数 this.config = { ...Oauth.config, ...config }; } } /** * 加载配置对象 * @param {object} obj 配置对象 */ Oauth.prototype.loadObj = function (obj) { $.push(this.config, obj); var f = this.config.main; if (f) { var file = f.fullname(this.getDir()); if (file.hasFile()) { var cs = require(file); if (cs) { $.push(this, cs); } } } }; /** * 身份验证主程序 * @param {object} ctx HTTP请求上下文 * @returns {object} 验证失败返回错误提示,验证通过返回null */ Oauth.prototype.main = async function (ctx) { return null; }; /** * 小校验 * @param {object} ctx HTTP请求上下文 */ Oauth.prototype.checkSub = async function (ctx) { }; /** * 验证身份 * @param {object} ctx HTTP请求上下文 * @returns {object} 验证失败返回错误提示,验证通过返回null */ Oauth.prototype.check = async function (ctx) { // 无需登录则不验证身份和权限 var cg = this.config; var user = await this._getUser(ctx); if (!cg.sign_in) { return null; } var error = await this.main(ctx); if (error) { return error; } if (!user) { return { code: 60000, message: '账户未登录!' }; } if (await this._checkAccess(user, cg)) { return { code: 70000, message: '没有访问权限' }; } return null; }; /** * 获取用户信息 * @param {object} ctx HTTP请求上下文 * @returns {object|null} 用户信息 * @private */ Oauth.prototype._getUser = async function (ctx) { var user = ctx.session?.user; if (user) { return user; } var token = ctx.headers[$.dict.token]; if (!token) { return null; } var u = await $.cache.get($.dict.session_id + '_' + token); if (!u) { return null; } var user_info = this._extractUserFromCache(u); if (user_info) { ctx.session.user = user_info; } return user_info; }; /** * 从缓存中提取用户信息 * @param {object|string} u 缓存数据 * @returns {object|null} 用户信息 * @private */ Oauth.prototype._extractUserFromCache = function (u) { var type = typeof (u); if (type === 'string') { var o = u.toJson(); return o.user; } else if (type === 'object' && Object.keys(u).length > 0) { return u.user; } return null; }; /** * 检查用户访问权限 * @param {object} user 用户信息 * @param {object} config 配置信息 * @returns {boolean} 是否无权限 * @private */ Oauth.prototype._checkAccess = function (user, config) { return this._checkAccessLevels(user, config) || this._checkUserGroups(user, config) || this._checkAdminGroups(user, config); }; /** * 检查用户级别权限 * @param {object} user 用户信息 * @param {object} config 配置信息 * @returns {boolean} 是否无权限 * @private */ Oauth.prototype._checkAccessLevels = function (user, config) { return (config.gm !== 0 && user.gm < config.gm) || (config.vip !== 0 && user.vip < config.vip) || (config.mc !== 0 && user.mc < config.mc); }; /** * 检查用户组权限 * @param {object} user 用户信息 * @param {object} config 配置信息 * @returns {boolean} 是否无权限 * @private */ Oauth.prototype._checkUserGroups = function (user, config) { if (config.user_group.length === 0) { return false; } var user_groups = user.user_group.split(','); var has_group = config.user_group.some(group => user_groups.includes(group)); return !has_group; }; /** * 检查管理组权限 * @param {object} user 用户信息 * @param {object} config 配置信息 * @returns {boolean} 是否无权限 * @private */ Oauth.prototype._checkAdminGroups = function (user, config) { if (config.user_admin.length === 0) { return false; } var admin_groups = user.user_admin.split(','); var has_admin = config.user_admin.some(group => admin_groups.includes(group)); return !has_admin; }; module.exports = Oauth;