这是我的models/users.ts文件:
import mongoose from 'mongoose';
const Schema = mongoose.Schema;
import passportLocalMongoose from 'passport-local-mongoose';
export interface digitalWalletDocument extends mongoose.Document{
currencyName: string;
value: number;
}
const digitalWalletSchema = new Schema<digitalWalletDocument>({
currencyName : {
type : String
},
value : {
type : Number
}
});
export interface UserDocument extends mongoose.Document{
username : String;
firstName : String;
lastName : String;
email : String;
telNumber : Number;
nationalCode : Number;
admin : Boolean;
image : String;
wallet : Number;
rate : Number;
shabaCode :Number;
cardNumber : Number;
birthDay : String;
status : String;
address : String;
documnetPath : String;
description : String;
purchased : String;
digitalWallet : digitalWalletDocument;
}
export const userSchema = new Schema<UserDocument>({
username : {
type : String,
sparse : true ,
unique : true
},
firstName : {
type: String
},
lastName : {
type : String
},
email : {
type : String,
unique : true
},
telNumber : {
type : Number
},
nationalCode : {
type : Number,
sparse : true,
unique : true
},
admin : {
type:Boolean,
default : false
},
image : {
type : String
},
wallet: {
type : Number,
default : 0
},
rate : {
type : Number,
default : 0
},
shabaCode : {
type : Number
},
cardNumber : {
type : Number
},
birthDay : {
type : String
},
status : {
type : String
},
address : {
type : String
},
documnetPath : {
type : String
},
description : {
type: String
},
purchased : [String],
digitalWallet : [digitalWalletSchema]
}, {timestamps : true});
export interface UserModel extends mongoose.Model<UserDocument> {};
userSchema.plugin(passportLocalMongoose,{usernameField : 'email'});
export default mongoose.model<UserDocument,UserModel>('User' , userSchema);下面是使用authentication.ts文件的user.ts文件:
import express, {Request, Response, NextFunction} from 'express';
import mongoose from 'mongoose';
import passport from 'passport';
import passportLocal from 'passport-local';
const LocalStrategy = passportLocal.Strategy;
import passportJWT from 'passport-jwt';
const passportJWTStrategy = passportJWT.Strategy;
const ExtractJWT = passportJWT.ExtractJwt;
import JWT from 'jsonwebtoken';
import User from './models/users';
import config from './config';
export const local = passport.use(new LocalStrategy( User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
exports.getToken = (user: any) => {
return JWT.sign(user, config.secretKey,{ expiresIn : "2d"});
};
const opt = {
secretOrKey : config.secretKey,
jwtFromRequest : ExtractJWT.fromAuthHeaderAsBearerToken()
};
export const jwtAuth = passport.use(new passportJWTStrategy(opt , (payload ,done) => {
User.findOne({_id : payload._id},(err: any , user: typeof User ) => {
if(err){
return done(err,false);
}
else if(user){
return done(null , user);
}
else{
return done(null, false);
}
});
}));
export const verifyUser = passport.authenticate('jwt', {session : false});
export function verifyAdmin(req: Request, res: Response, next: NextFunction) {
if(req.user.admin){
return next();
}
else{
let err = new Error('Only Admin can access to this web page or resources!');
err.status = 403;
return next(err);
}
}我收到以下错误消息:
Property 'authenticate' does not exist on type 'UserModel'.ts(2339)
Property 'serializeUser' does not exist on type 'UserModel'.ts(2339)
Property 'deserializeUser' does not exist on type 'UserModel'.ts(2339)造成错误的原因是以下几行:
export const local = passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());我不知道是什么问题,我如何解决它?我试着在网上搜索,找到类似的问题,做类似问题的答案,但没有一个对我有用!
EDIT:我修改了代码,就像@Linda在她的回答中建议的那样。但出现了以下新错误:
没有过载和这个电话匹配。重载2中的1,'(fn:(user: User,done:(err: any,id?:any) => void) => void):=>‘,给出了以下错误。类型'(user: UserDocument,cb:(err: any,id?:any) => void) => void‘的参数“(User: User,done:(err: any,id?:any) => void) => =>’。参数'user‘和'user’的类型是不兼容的。类型‘UserDocument’中缺少以下属性:用户名、firstName、lastName、电子邮件和66更多。 重载2中的2,'(fn:(req: IncomingMessage,user: User,done:(err: any,id?:=> void) => void)=> void):=>‘,给出了以下错误。
错误发生在代码的这一行:
passport.serializeUser(User.serializeUser());在authentication.ts文件上。
当我删除User.serializeUser()前面的括号时,错误会消失,但我不确定是否是这样。
发布于 2022-04-30 16:59:06
问题
给出错误的字段是由passport-local-mongoose包添加的字段。
当你打电话:
userSchema.plugin(passportLocalMongoose, {usernameField : 'email'});您正在将这些附加字段(如authenticate()和serializeUser() )添加到模型中。
不幸的是,用于类型声明的猫鼬Schema.plugin()表示,它返回与其启动时相同的对象类型:
/** Registers a plugin for this schema. */
plugin(fn: (schema: Schema<DocType>, opts?: any) => void, opts?: any): this;因此,您的代码无法自动检测这些添加的属性。
解决方案
步骤1:
安装@types/passport-local-mongoose以加载passport-local-mongoose包的类型声明。
npm i --save-dev @types/passport-local-mongoose附加类型被添加到mongoose命名空间中,因此您可以使用mongoose.TypeName访问它们,就像访问标准猫鼬类型一样。
第2步:
声明您的UserModel接口是PassportLocalModel而不是普通的Model。
export interface UserModel extends mongoose.PassportLocalModel<UserDocument> {};您需要保留已经在这里调用mongoose.model()的泛型类型参数:
export default mongoose.model<UserDocument, UserModel>('User' , userSchema);但是现在您的User模型将具有方法 of a PassportLocalModel!
另外,您希望在您的string接口中使用小写的TypeScript和number。
https://stackoverflow.com/questions/71934042
复制相似问题