admin_authority.ts 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import { Context } from 'egg';
  2. import * as _ from 'lodash';
  3. // 无需token的地址
  4. const noTokenUrl = [
  5. '/admin/captcha/img',
  6. '/admin/login',
  7. '/admin/tg/tgboot/test',
  8. ];
  9. const noPermUrl = [
  10. '/admin/permmenu',
  11. '/admin/person',
  12. '/admin/logout',
  13. // '/admin/role_menu',
  14. ];
  15. /**
  16. * Admin权限验证中间件,只检测/admin开头请求
  17. * Token验证通过会把当前解析的Token解析把对象挂载到ctx.token上,token对象例如{ uid, pv }
  18. */
  19. export default function AdminAuthority(): any {
  20. return async (ctx: Context, next: () => Promise<any>) => {
  21. const { url } = ctx;
  22. let statusCode = 200;
  23. let errorCode = 0;
  24. const token = ctx.get('Authorization');
  25. if (_.startsWith(url, '/admin')) {
  26. if (noTokenUrl.includes(url.split('?')[0])) {
  27. await next();
  28. return;
  29. }
  30. try {
  31. ctx.token = ctx.helper.jwtVerify(token);
  32. } catch (e) {
  33. statusCode = 401;
  34. errorCode = 11001;
  35. }
  36. if (ctx.token) {
  37. if (noPermUrl.includes(url.split('?')[0])) {
  38. await next();
  39. return;
  40. }
  41. const pv = await ctx.service.admin.comm.verify.getRedisPasswordVersionById(ctx.token.uid);
  42. if (pv !== `${ctx.token.pv}`) {
  43. // 判断密码版本,防止登录时更改密码还在允许使用
  44. errorCode = 11002;
  45. statusCode = 401;
  46. } else {
  47. const redisToken = await ctx.service.admin.comm.verify.getRedisTokenById(ctx.token.uid);
  48. // 查询token是否一致
  49. if (token !== redisToken) {
  50. errorCode = 11002;
  51. statusCode = 401;
  52. } else {
  53. // 遍历权限是否包含该url,不包含则无访问权限
  54. let perms = await ctx.service.admin.comm.verify.getRedisPermsById(ctx.token.uid);
  55. if (_.isEmpty(perms)) {
  56. errorCode = 11001;
  57. statusCode = 403;
  58. } else {
  59. // 将sys:admin:user等转换成sys/admin/user
  60. perms = JSON.parse(perms!).map(e => {
  61. return e.replace(/:/g, '/');
  62. });
  63. if (!perms!.includes(url.split('?')[0].replace('/admin/', ''))) {
  64. errorCode = 11003;
  65. statusCode = 403;
  66. }
  67. }
  68. }
  69. }
  70. }
  71. if (statusCode > 200) {
  72. ctx.status = 200;
  73. ctx.body = {
  74. code: errorCode,
  75. message: ctx.helper.getErrorMessageByCode(`${errorCode}`),
  76. };
  77. return;
  78. }
  79. }
  80. // has perms, pass
  81. await next();
  82. };
  83. }