Install
npm i egg-bag-framework
Built-in multiple modules, middleware and tools
Source code address ,
demo address
middleware
Verify whether the Sing signature is legal to prevent arbitrary requests
'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 signature has expired' }); // Expired if present } 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 signature is illegal, missing string' }); } } catch (e) { ctx. body = ctx. resultData ({ msg : 'sing signature is illegal' }); } } } else { ctx.body = ctx.resultData ({ msg : ' Missing sing signature' }) ; } }; };
Current limiting middleware
Prevent the interface from being maliciously stolen. If it is attacked, request to use nginx or server configuration white and blacklist
'use strict' ; const { RateLimiterMemory } = require ( 'rate-limiter-flexible' ); // Rate limiting middleware module . exports = () => { // Create a memory-based token bucket rate limiter, Limit 12 requests per second 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 : 'Current limiting triggered' , code : 2001 }); }); }; };
Verifyjwt
'use strict' ; module . exports = () => { return async function authority ( ctx, next ) { const authorization = ctx. request . header . authorization ; if (authorization) { try { ctx. helper . verifyToken (authorization); // Verify jwt await next (); } catch (err) { ctx. body = ctx. resultData ({ msg : 'access_token expired' , code : 1003 }); } } else { ctx. body = ctx. resultData ({ msg : 'missing access_token' , code : 1003 }); } }; };
Built-in module
jwt
(JWT) is an open standard (RFC 7519) that defines a compact, self-contained way to securely transmit information between parties as JSON objects. This information can be verified and trusted because it is digitally signed
// plugin.js exports . jwt = { enable : true , package : 'egg-jwt' , };
// config.default.js config. jwt = { secret : 'ABCD20231017QWERYSUNXSJL' , // You can customize the sign : { expiresIn : 8 * 60 * 60 , // Expiration time is 8 hours }, };
Validate
Parameter verification module
// 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 is an open source (BSD licensed), in-memory data structure server that can be used as a database, cache, and message queue broker
// 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
local cache
exports . lru = { enable : true , package : 'egg-lru' , // local cache };
config. lru = { client : { max : 3000 , // All lru cache configurations are available maxAge : 1000 * 60 * 30 , // 60 min cache }, app : true , // Loaded into the app, the default is open agent : false , // Loaded into the agent, the default is closed };
Upload mode
// config.default.js config. multipart = { mode : 'file' , fileSize : '50mb' , // Receive file size whitelist : [ // Allowed file types to be received '.png' , '.jpg' , ' .webp' , '.gif' , '.zip' , '.doc' , '.docx' , '.txt' , '.xlsx' , '.pdf' , '.mp4' , '.webm' , ' .mov' , '.flv' , '.avi' , '.f4v' , '.mov' , '.m4v' , '.rmvb' , '.rm' , '.mpg' , '.mpeg' , ], };
Sequelize
Sequelize is a promise-based Node.js ORM that currently supports Postgres , MySQL , MariaDB , SQLite and Microsoft SQL Server . It has powerful transaction support, relationships, pre-reading and delayed loading, read replication and other functions
// 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 is the most popular relational database management system. In terms of WEB applications, MySQL is one of the best RDBMS (Relational Database Management System) application software.
// plugin.js exports . mysql = { enable : true , package : 'egg-mysql' , };
// config.default.js config. mysql = { client : { // host host : '127.0.0.1' , // port number port : '3306' , // username user : 'pm_webleading' , // password password : '123456' , // Database name database : 'pm_webleading' , }, // Whether to load on the app, the app will be enabled by default : true , // Whether to load on the agent, the agent will be disabled by default : false , };
Built-in tools
The method called on the egg.js and ctx objects is as follows
'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 ;
Upload files locally
Files of the above configuration types can be uploaded
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); // Read the file const source = fs. createReadStream (file. filepath ); // Create a write stream const target = fs. createWriteStream (localPath); await pump (source, target); resolve (_filePath); } catch (err) { reject (err); } }); }
Upload images – with compression
Only pictures can be uploaded
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) ; }); }); }
Symmetric encryption
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 (); // Symmetric encryption content },
Symmetric decryption
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); // Symmetrically decrypted content },
asymmetric encryption
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); // Asymmetric encrypted string },
Asymmetric decryption
decrypt ( str, options ) { options = Object . assign ({ privateKey : this . app . config . website . privateKey }, options); const decrypted = new JSEncrypt (); // Create a decryption object instance decrypted. setPrivateKey (options. privateKey . toString ()); // Set the private key return decrypted. decrypt (str); // Asymmetric decryption content },
md5 encryption
md5 ( data ) { let str = data; if ( typeof data === 'object' ) { str = JSON . stringify (data); } return CryptoJS . MD5 (str) .toString ( ); },
Random ID
nanoid ( size = 12 ) { const nanoid = customAlphabet (alphabet. join ( '' ), size); if (size >= 12 ) { return dayjs () . format ( 'YYYYMMDD' ) + nanoid (); // Get a unique random ID } return nanoid (); // Get repeated random ID },
jwt-generate token-verify token
generateToken ( data ) { return this . app . jwt . sign (data, this . app . config . jwt . secret ); // Generate token }, verifyToken ( token ) { return this . app . jwt . verify (token, this . app . config . jwt . secret ); // Verify token },