剧场模式
首页后端TypeScript基于角色的权限控制原理与实战

基于角色的权限控制原理与实战 #2 Admin Model

海外散仙厉飞雨 · 化神发布于新课程
0

src/app.ts

import express, { Express, Request, Response } from "express";

// database
import mongoose from "mongoose";

// error handler
import errorMiddleware from "./middlewares/error.middleware";

// config
import "dotenv/config";
import config from "./config/config";

// middleware
import morgan from "morgan";
import helmet from "helmet";
import cors from "cors";
import routes from "./routes";

// logger
import { Logger, ILogger } from "./utils/logger";
import notFoundError from "./middlewares/notFoundHandler.middleware";

// model
import User from "./models/User";

import bcrypt from "bcryptjs";
import Admin from "./models/Admin";

export class Application {
  app: Express;
  config = config;
  logger: ILogger;

  constructor() {
    this.logger = new Logger(__filename);
    this.app = express();
    this.app.use(require("express-status-monitor")());
    this.app.use(helmet());
    this.app.use(cors());
    this.app.use(
      morgan("dev", {
        skip: () => config.environment === "test"
      })
    );

    this.app.use(express.json());
    this.app.use(express.urlencoded({ extended: true }));

    this.app.get("/", (_req: Request, res: Response) => {
      res.json({
        message: "hello world"
      });
    });

    this.app.use("/api", routes);

    this.app.use(notFoundError);

    this.app.use(errorMiddleware);
  }

  setupDbAndServer = async () => {
    await this.setupDb();
    await this.startServer();
    await this.createUser();
    await this.createAdmin();
  };

  setupDb = async () => {
    mongoose.set("useFindAndModify", false);
    const mongodbUrl = `${config.db.host}:${config.db.port}/${config.db.database}`;
    await mongoose.connect(mongodbUrl, {
      useNewUrlParser: true,
      useUnifiedTopology: true
    });
    this.logger.info(`Connected to database. Connection: ${mongodbUrl}`);
  };

  startServer = (): Promise<boolean> => {
    return new Promise((resolve, _reject) => {
      this.app
        .listen(+this.config.port, this.config.host, () => {
          this.logger.info(
            `Server started at http://${this.config.host}:${this.config.port}`
          );
          resolve(true);
        })
        .on("error", err => console.error(err));
    });
  };

  createAdmin = async (): Promise<any> => {
    try {
      const superAdmin = await Admin.findOne({
        username: config.superAdmin.username
      });
      if (superAdmin) return;

      const superHashedPassword = await bcrypt.hash(
        config.superAdmin.password,
        10
      );

      let newSuperAdmin = new Admin({
        username: config.superAdmin.username,
        password: superHashedPassword
      });

      await newSuperAdmin.save();

      const basicAdmin = await Admin.findOne({
        username: config.basicAdmin.username
      });
      if (basicAdmin) return;

      const basicHashedPassword = await bcrypt.hash(
        config.superAdmin.password,
        10
      );

      let newBasicAdmin = new Admin({
        username: config.basicAdmin.username,
        password: basicHashedPassword
      });

      await newBasicAdmin.save();
    } catch (error) {
      return Promise.reject(error);
    }
  };

  createUser = async (): Promise<any> => {
    try {
      const user = await User.findOne({ username: config.user.username });
      if (user) return;

      const hashedPassword = await bcrypt.hash(config.user.password, 10);

      let newUser = new User({
        username: config.user.username,
        password: hashedPassword,
        email: config.user.email
      });

      await newUser.save();
    } catch (error) {
      return Promise.reject(error);
    }
  };
}

src/models/Admin.ts

import jwt from "jsonwebtoken";
import { Schema, model, Model, Document } from "mongoose";
import { AdminJwtPayload } from "../types/Jwt";
import config from "../config/config";

export interface IAdminDocument extends Document {
  username: string;
  password: string;
  generateToken: () => string;
}

const adminSchema: Schema = new Schema(
  {
    username: String,
    password: String
  },
  { timestamps: true }
);

adminSchema.methods.generateToken = function(): string {
  const payload: AdminJwtPayload = { id: this.id };
  return jwt.sign(payload, config.auth.adminSecretKey, {
    expiresIn: "5d"
  });
};

adminSchema.set("toJSON", {
  transform: function(_doc, ret) {
    delete ret["password"];
    return ret;
  }
});

const Admin: Model<IAdminDocument> = model<IAdminDocument>(
  "Admin",
  adminSchema
);

export default Admin;

src/types/Jwt.ts

import { IUserDocument } from "../models/User";
import { IAdminDocument } from "src/models/Admin";

export interface JwtPayload {
  id: IUserDocument["_id"];
  username: IUserDocument["username"];
}

export interface AdminJwtPayload {
  id: IAdminDocument["_id"];
}
0 条回复
暂无回复~~
订阅号服务号小程序(beta)
随机课程
跟我一起学 React + dva + Mockjs

跟我一起学 React + dva + Mockjs

9 个视频34 分钟中级

Pro¥ 69.00¥ 55.20

前端React已完结

学员
cuihanwen666 · 元婴cometjun · 道祖ican · 大乘sdrb001 · 练虚terry · 太乙YJeremy · 真仙🔆 · 金仙songtianen · 道祖
最新动态
cuihanwen666 · 元婴学习到了0:00
cometjun · 道祖学习到了0:00
ican · 大乘学习到了1:33
sdrb001 · 练虚学习到了3:20
terry · 太乙学习到了0:00
统计信息
    学员: 14720
    视频数量: 852
    帖子数量: 420

© 汕尾市求知科技有限公司 | 粤ICP备19038915号 | 在线学员:90

Top