【问题标题】:How do I get expected types on express request argument如何在快速请求参数上获得预期类型
【发布时间】:2020-05-11 18:44:36
【问题描述】:

我正在使用护照和打字稿在快速应用程序中进行一些身份验证。我已经使用 typegoose 定义了一个用户模型。通过护照策略传递登录请求后,我正在调用一个返回令牌的登录方法。我在req.user._id Property '_id' does not exist on type 'User'. 上遇到打字错误

我没有在我的用户模型上明确定义_id,但是根据我对 typegoose 的理解,这是不必要的,并且代码中的其他地方我没有这个问题。此外,尝试在模型上明确定义的内容(电子邮件、zip 等)仍然会产生相同的错误。

import { Request, Response, Router } from 'express';
import jwt from 'jwt-simple';
import passport from 'passport';
import 'dotenv/config';

import ControllerInterface from './controller.interface';

class LoginController implements ControllerInterface {
  public path = '/api/login';
  public router = Router();

  constructor() {
    this.initRoutes();
  }

  public initRoutes(): any {
    this.router.post(this.path, [this.requireLogin, this.login]);
  }

  tokenForUser = (id: string) => {
    const timestamp = new Date().getTime();
    return jwt.encode({ sub: id, iat: timestamp }, process.env.JWT_ENCRYPTION);
  };

  requireLogin = passport.authenticate('local', { session: false });

  login = (req: Request, res: Response) => {
    // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
    // @ts-ignore
    res.send({ token: this.tokenForUser(req.user._id) });
  };
}

export default LoginController;

护照策略是使用我用typegoose创建的用户模型

const local = new LocalStrategy(localOptions, (email, password, done) => {
  UserModel.findOne({ email }, async (err: NodeJS.ErrnoException, user) => {
    if (err) return done(err);
    if (!user) return done(null, false);

    const isMatch = await user.comparePassword(password);

    if (!isMatch) return done(null, false);
    return done(null, user);
  });
});

我已经搜索了很多,但没有运气,谢谢!

编辑:添加用户模型代码

import bcrypt from 'bcrypt';
import jwt from 'jsonwebtoken';
import 'dotenv/config';

import { arrayProp, getModelForClass, pre, prop } from '@typegoose/typegoose';

const setUserId = () => {
  return Math.random()
    .toString(36)
    .substr(2, 9);
};

const getUserId = (id: string) => {
  return id;
};

@pre<UserClass>('save', async function(next) {
  if (this.isModified('password') || this.isNew) {
    const hashedPass = await bcrypt.hash(this.password, 10);
    this.password = hashedPass;
    this.updated = new Date();
    next();
  }
})
class UserClass {
  @prop()
  public firstName?: string;

  @prop()
  public lastName?: string;

  public get fullName(): string {
    return `${this.firstName} ${this.lastName}`;
  }

  public set fullName(full) {
    const [firstName, lastName] = full.split(' ');
    this.firstName = firstName;
    this.lastName = lastName;
  }

  @prop({
    required: true,
    unique: true,
    lowercase: true,
    trim: true,
    validate: {
      validator: (email) => {
        const emailRegExp = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
        return emailRegExp.test(email);
      },
      message: 'Email is invalid.',
    },
  })
  public email!: string;

  @prop({
    required: true,
    validate: {
      validator: (password) => {
        // at least 8 char
        // at least 1 number
        // at least 1 special character
        const passwordRegExp = /^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!%*#?&]{8,}$/;
        return passwordRegExp.test(password);
      },
      message: 'Password is not in the proper format.',
    },
  })
  public password!: string;

  @prop({ default: Date.now })
  public created?: Date;

  @prop()
  public updated?: Date;

  @prop({ unique: true, set: setUserId, get: getUserId, default: setUserId() })
  public userId?: string;

  async comparePassword(candidatePassword: string): Promise<boolean> {
    const isMatch = await bcrypt.compare(candidatePassword, this.password);
    return isMatch;
  }

  getJWT(): string {
    const expirationTime = parseInt(process.env.JWT_EXPIRATION, 10);
    const bearer = jwt.sign({ userId: this.userId }, process.env.JWT_ENCRYPTION, {
      expiresIn: expirationTime,
    });
    return `Bearer ${bearer}`;
  }

  toWeb(): object {
    return this;
  }
}

const UserModel = getModelForClass(UserClass);

export { UserClass };
export default UserModel;

【问题讨论】:

    标签: node.js typescript express passport.js


    【解决方案1】:

    您必须在创建用户模型时添加行 const { _id: id } = await UserModel.create({ .... } as User)

    【讨论】:

    • 我正在使用 typegoose 创建我的用户模型。我将代码添加到问题中。
    猜你喜欢
    • 2021-11-13
    • 2017-03-08
    • 1970-01-01
    • 2020-12-27
    • 2016-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多