【发布时间】: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