動態

詳情 返回 返回

基於Egg.js二次封裝框架,一鍵安裝,乾貨上場 - 動態 詳情


highlight: agate

theme: fancy

安裝

npm i egg-bag-framework

內置多種模塊,中間件以及工具

源碼地址,
演示地址

中間件

校驗sing簽名是否合法,防止隨意發起請求

'use strict';
module.exports = (option, app) => {
    return async function sing(ctx, next) {
        const sing = ctx.request.header.sing;
        const { domain, expireTime, cache } = ctx.app.config.website;
        const default_cache = 'redis';
        if (sing) {
            let getSing = null;
            if (cache === default_cache) {
                getSing = await app.redis.get(sing);
            } else {
                getSing = await app.lru.get(sing);
            }
            if (getSing) {
                ctx.body = ctx.resultData({ msg: 'sing簽名已過期' }); // 在存在説明既過期
            } else {
                try {
                    const decSing = ctx.helper.aesDecrypt(sing);
                    const singData = JSON.parse(decSing);
                    if (singData.domain === domain) {
                        if (cache === default_cache) {
                            await app.redis.set(sing, 1);
                        } else {
                            await app.lru.set(sing, 1);
                        }
                        await app.redis.set(sing, 1);
                        await app.redis.expire(sing, expireTime);
                        await next();
                    } else {
                        ctx.body = ctx.resultData({ msg: 'sing簽名不合法,缺少字符串' });
                    }
                } catch (e) {
                    ctx.body = ctx.resultData({ msg: 'sing簽名不合法' });
                }
            }
        } else {
            ctx.body = ctx.resultData({ msg: '缺少sing簽名' });
        }
    };
};

限流中間件

防止接口被惡意盜刷,如果被攻擊了,請求使用nginx或者服務器配置白黑名單

'use strict';
const { RateLimiterMemory } = require('rate-limiter-flexible'); // 限流中間件
module.exports = () => {
    // 創建一個基於內存的令牌桶速率限制器,每秒限制 12 次請求
    const opts = {
        points: 12,
        duration: 1,
    };
    const rateLimiter = new RateLimiterMemory(opts);
    return async function limiter(ctx, next) {
        rateLimiter.consume(ctx.request.ip)
            .then(rateLimiterRes => {
                next();
            })
            .catch(rateLimiterRes => {
                ctx.body = ctx.resultData({ msg: '觸發限流了', code: 2001 });
            });
    };
};

驗證jwt

'use strict';

module.exports = () => {
    return async function authority(ctx, next) {
        const authorization = ctx.request.header.authorization;
        if (authorization) {
            try {
                ctx.helper.verifyToken(authorization); // 驗證jwt
                await next();
            } catch (err) {
                ctx.body = ctx.resultData({ msg: 'access_token過期', code: 1003 });
            }
        } else {
            ctx.body = ctx.resultData({ msg: '缺少access_token', code: 1003 });
        }
    };
};

內置模塊

jwt

(JWT)是一個開放標準(RFC 7519),它定義了一種緊湊的、自包含的方式,用於作為JSON對象在各方之間安全地傳輸信息。該信息可以被驗證和信任,因為它是數字簽名的

// plugin.js
exports.jwt = {  
    enable: true,  
    package: 'egg-jwt',  
};
// config.default.js
config.jwt = {  
    secret: 'ABCD20231017QWERYSUNXSJL', // 可以自定義  
    sign: {  
        expiresIn: 8 * 60 * 60, // 過期時間8小時  
    },  
};

Validate

參數校驗模塊

// plugin.js
exports.validate = {  
    enable: true,  
    package: 'egg-validate',  
};
// config.default.js
config.validate = {  
    convert: true,  
    translate() {  
        const args = Array.prototype.slice.call(arguments);  
        return I18n.__.apply(I18n, args);  
    },  
};

redis

Redis是一個開源(BSD許可),內存存儲的數據結構服務器,可用作數據庫,高速緩存和消息隊列代理

// plugin.js
exports.redis = {  
    enable: true,  
    package: 'egg-redis',  
};
// config.default.js
config.redis = {  
    client: {  
        port: 6379,  
        host: '127.0.0.1',  
        password: 'auth',  
        db: 0,  
    },  
}

lru

本地緩存

exports.lru = {  
    enable: true,  
    package: 'egg-lru', // 本地緩存  
};
config.lru = {  
    client: {  
        max: 3000, // 所有lru緩存配置可用  
        maxAge: 1000 * 60 * 30, // 60 min cache  
    },  
    app: true, // 加載到app中,默認是打開的  
    agent: false, // 加載到代理中,默認為關閉  
};

上傳模式

// config.default.js
config.multipart = {  
    mode: 'file',  
    fileSize: '50mb', // 接收文件大小  
    whitelist: [ // 允許接收的文件類型  
        '.png',  
        '.jpg',  
        '.webp',  
        '.gif',  
        '.zip',  
        '.doc',  
        '.docx',  
        '.txt',  
        '.xlsx',  
        '.pdf',  
        '.mp4',  
        '.webm',  
        '.mov',  
        '.flv',  
        '.avi',  
        '.f4v',  
        '.mov',  
        '.m4v',  
        '.rmvb',  
        '.rm',  
        '.mpg',  
        '.mpeg',  
    ],  
};

Sequelize

Sequelize 是一個基於 promise 的 Node.js ORM, 目前支持 PostgresMySQLMariaDBSQLite 以及 Microsoft SQL Server. 它具有強大的事務支持, 關聯關係, 預讀和延遲加載,讀取複製等功能

// plugin.js
exports.sequelize = {  
    enable: true,  
    package: 'egg-sequelize',  
};
config.sequelize = {  
    dialect: 'mysql',  
    database: 'pm_webleading',  
    host: '127.0.0.1',  
    port: '3306',  
    username: 'pm_webleading',  
    password: '123456',  
    underscored: false,  
    timezone: '+08:00',  
    define: {  
        timestamps: true,  
        freezeTableName: true,  
    },  
};

Mysql

MySQL 是最流行的關係型數據庫管理系統,在 WEB 應用方面 MySQL 是最好的 RDBMS(Relational Database Management System:關係數據庫管理系統)應用軟件之一

// plugin.js
exports.mysql = {  
    enable: true,  
    package: 'egg-mysql',  
};
// config.default.js
config.mysql = {  
    client: {  
    // host  
    host: '127.0.0.1',  
    // 端口號  
    port: '3306',  
    // 用户名  
    user: 'pm_webleading',  
    // 密碼  
    password: '123456',  
    // 數據庫名  
    database: 'pm_webleading',  
    },  
    // 是否加載到 app 上,默認開啓  
    app: true,  
    // 是否加載到 agent 上,默認關閉  
    agent: false,  
};

內置工具

已掛在egg.js,ctx對象上調用方法如下

'use strict';  
  
const {Controller} = require('egg');  
  
class HomeController extends Controller {  
    async index() {  
       const {ctx} = this;  
        try {  
            for (const file of ctx.request.files) {  
               const filePath = await ctx.helper.uploadLocaFile({file})  // cxt.helper.xxxx
            }  
        } finally {  
           await ctx.cleanupRequestFiles();  
        }  
    }
}
module.exports = HomeController;

上傳文件本地

可以上傳以上配置類型的文件

uploadLocaFile({ file, filePath }) {  
    const { ctx } = this;  
    return new Promise(async (resolve, reject) => {  
        try {  
            const filename = file.filename;  
            const extname = path.extname(filename);  
            const _filePath = filePath || `public/upload/${ctx.helper.nanoid()}${extname}`;  
            const localPath = path.join(ctx.app.baseDir, 'app', _filePath);  
            // 讀取文件  
            const source = fs.createReadStream(file.filepath);  
            // 創建寫入流  
            const target = fs.createWriteStream(localPath);  
            await pump(source, target);  
            resolve(_filePath);  
        } catch (err) {  
            reject(err);  
        }  
    });  
}

上傳圖片-帶壓縮

只能上傳圖片

uploadLocalImage({ file, filePath, width = 500, quality = 75 }) {
        const { ctx } = this;
        const extname = path.extname(file.filename);
        const _filePath = filePath || `public/image/${ctx.helper.nanoid()}${extname}`;
        const localPath = path.join(ctx.app.baseDir, 'app', _filePath);
        return new Promise((resolve, reject) => {
            Jimp.read(file.filepath)
                .then(image => {
                    image.resize(width, Jimp.AUTO)
                        .quality(quality)
                        .write(localPath);
                    resolve(_filePath);
                })
                .catch(err => {
                    reject(err);
                });
        });
    }

對稱加密

aesEncrypt(data, options) {
        options = Object.assign({ key: this.app.config.website.key, iv: this.app.config.website.iv }, options);
        let str = data;
        if (typeof data === 'object') {
            str = JSON.stringify(data);
        }
        str = CryptoJS.enc.Utf8.parse(str);
        const crypto = CryptoJS.AES.encrypt(str, CryptoJS.enc.Utf8.parse(options.key), {
            iv: CryptoJS.enc.Utf8.parse(options.iv),
            mode: CryptoJS.mode.ECB,
            padding: CryptoJS.pad.Pkcs7,
        });
        return crypto.toString(); // 對稱加密內容
    },

對稱解密

aesDecrypt(data, options) {
        options = Object.assign({ key: this.app.config.website.key, iv: this.app.config.website.iv }, options);
        const decrypt = CryptoJS.AES.decrypt(data, CryptoJS.enc.Utf8.parse(options.key), {
            iv: CryptoJS.enc.Utf8.parse(options.iv),
            mode: CryptoJS.mode.ECB,
            padding: CryptoJS.pad.Pkcs7,
        });
        return CryptoJS.enc.Utf8.stringify(decrypt); // 對稱解密內容
    },

非對稱加密

 encrypt(str, options) {
        options = Object.assign({ publicKey: this.app.config.website.publicKey }, options);
        const encrypted = new JSEncrypt();
        encrypted.setPublicKey(options.publicKey.toString());
        return encrypted.encrypt(str); // 非對稱加密字符串
    },

非對稱解密

decrypt(str, options) {
        options = Object.assign({ privateKey: this.app.config.website.privateKey }, options);
        const decrypted = new JSEncrypt(); // 創建解密對象實例
        decrypted.setPrivateKey(options.privateKey.toString()); // 設置私鑰
        return decrypted.decrypt(str); // 非對稱解密內容
    },

md5加密

md5(data) {
        let str = data;
        if (typeof data === 'object') {
            str = JSON.stringify(data);
        }
        return CryptoJS.MD5(str)
            .toString();
    },

隨機ID

nanoid(size = 12) {
        const nanoid = customAlphabet(alphabet.join(''), size);
        if (size >= 12) {
            return dayjs()
                .format('YYYYMMDD') + nanoid(); // 獲取不重複隨機ID
        }
        return nanoid(); // 獲取重複隨機ID

    },

jwt-生成token-校驗token

generateToken(data) {
        return this.app.jwt.sign(data, this.app.config.jwt.secret); // 生成token
    },
    verifyToken(token) {
        return this.app.jwt.verify(token, this.app.config.jwt.secret); // 驗證token
    },
user avatar nihaojob 頭像 huajianketang 頭像 u_17443142 頭像 yulong1992 頭像 xw-01 頭像 huangmingji 頭像 abc-x 頭像 DolphinScheduler 頭像 yanyue404 頭像 lizhiqianduan 頭像 morimanong 頭像 prosuoqi 頭像
點贊 60 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.