import { Provide } from '@midwayjs/decorator' ; import { IMidwayWebNext , IWebMiddleware , MidwayWebMiddleware , } from '@midwayjs/web' ; import { Context } from 'egg' ; import { isEmpty } from 'lodash' ; import { res , Utils } from '../common/utils' ; import { ResOp } from '../interface' ; import { AdminVerifyService } from '../service/admin/comm/verify' ; import { ADMIN_PREFIX_URL , NOPERM_PREFIX_URL , NOAUTH_PREFIX_URL , } from '../controller/base' ; @ Provide ( ) export class AdminAuthMiddleware implements IWebMiddleware { resolve ( ) { return async ( ctx , next ) => { const url = ctx . url ; const path = url . split ( '?' ) [ 0 ] ; const token = ctx . get ( 'Authorization' ) ; if ( url . startsWith ( `${ ADMIN_PREFIX_URL }/` ) ) { if ( url . startsWith ( `${ ADMIN_PREFIX_URL }${ NOAUTH_PREFIX_URL }/` ) ) { await next ( ) ; return ; } if ( isEmpty ( token ) ) { this . reject ( ctx , { code : 11001 } ) ; return ; } const utils = await ctx . requestContext . getAsync ( Utils ) ; try { ctx . admin = utils . jwtVerify ( token ) ; } catch ( e ) { this . reject ( ctx , { code : 11001 } ) ; return ; } if ( ! ctx . admin ) { this . reject ( ctx , { code : 11001 } ) ; return ; } const verifyService = await ctx . requestContext . getAsync ( AdminVerifyService ) ; const pv = await verifyService . getRedisPasswordVersionById ( ctx . admin . uid ) ; if ( pv !== `${ ctx . admin . pv }` ) { this . reject ( ctx , { code : 11002 } ) ; return ; } const redisToken = await verifyService . getRedisTokenById ( ctx . admin . uid ) ; if ( token !== redisToken ) { this . reject ( ctx , { code : 11002 } ) ; return ; } if ( url . startsWith ( `${ ADMIN_PREFIX_URL }${ NOPERM_PREFIX_URL }/` ) ) { await next ( ) ; return ; } const perms = await verifyService . getRedisPermsById ( ctx . admin . uid ) ; if ( isEmpty ( perms ) ) { this . reject ( ctx , { code : 11001 } ) ; return ; } const permArray = ( JSON . parse ( perms ) as string [ ] ) . map ( e => { return e . replace ( /:/g , '/' ) ; } ) ; if ( ! permArray . includes ( path . replace ( '/admin/' , '' ) ) ) { this . reject ( ctx , { code : 11003 } ) ; return ; } } await next ( ) ; } ; } reject ( ctx , op ) { ctx . status = 200 ; ctx . body = res ( op ) ; } }