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

基于角色的权限控制原理与实战 #4 后台用户登录(四更)

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

src/routes/index.ts

import express, { Router } from "express";
import usersRouter from "./users";
import postsRouter from "./posts";
import adminRouter from "./admin";

const router: Router = express.Router();

router.use("/users", usersRouter);
router.use("/posts", postsRouter);

router.use("/admin", adminRouter);

export default router;

src/routes/admin/index.ts

import express, { Router } from "express";
import usersRouter from "./users";

const router: Router = express.Router();

router.use("/users", usersRouter);

export default router;

src/routes/admin/users.ts

import express, { Router } from "express";
import * as usersController from "../../controllers/admin/users";

const router: Router = express.Router();

router.post("/login", usersController.postLogin);

export default router;

src/utils/admin/validator.ts

import { isEmpty } from "validator";
import { IAdminDocument } from "../../models/Admin";

export interface InputError extends Partial<IAdminDocument> {
  general?: string;
}

export const validateInput = (
  username: IAdminDocument["username"],
  password: IAdminDocument["password"]
) => {
  let errors: InputError = {};

  if (isEmpty(username.trim())) {
    errors.username = "Username must not be empty";
  }

  if (isEmpty(password.trim())) {
    errors.password = "Password must not be empty";
  }

  return { errors, valid: Object.keys(errors).length < 1 };
};

src/controllers/admin/users.ts

import { Request, Response } from "express";

import { InputError, validateInput } from "../../utils/admin/validator";
import HttpException from "../../exceptions/HttpException";
import { UNPROCESSABLE_ENTITY } from "http-status-codes";

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

import { wrapAsync } from "../../helpers/wrap-async";

const throwValidateError = (errors: InputError) => {
  throw new HttpException(UNPROCESSABLE_ENTITY, "Admin input error", errors);
};

/**
 * Login Admin
 *
 * @Method POST
 * @URL /api/admin/users/login
 *
 */
export const postLogin = wrapAsync(
  async (req: Request, res: Response): Promise<void> => {
    const { username, password } = req.body;

    const { errors, valid } = validateInput(username, password);

    if (!valid) {
      return throwValidateError(errors);
    }

    const admin = await Admin.findOne({ username });

    if (!admin) {
      errors.general = "Admin not found";
      return throwValidateError(errors);
    }

    const match = await bcrypt.compare(password, admin.password);

    if (!match) {
      errors.general = "Wrong credentials";
      return throwValidateError(errors);
    }

    const token = admin.generateToken();

    res.json({
      success: true,
      data: {
        id: admin.id,
        token
      }
    });
  }
);
0 条回复
暂无回复~~
订阅号服务号小程序(beta)
随机课程
程序世界之速成课

程序世界之速成课

6 个视频1 小时 38 分钟中级

Pro¥ 39.00¥ 31.20

其他其他已完结

学员
yanger0000 · 元婴🔆 · 金仙
最新动态
yanger0000 · 元婴学习到了0:19
🔆 · 金仙学习到了10:44
统计信息
    学员: 14720
    视频数量: 852
    帖子数量: 420

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

Top