我在this starter project的基础上构建,并尝试使用passport-local-mongoose添加用户登录。
根据我尝试使用策略的两种方式中的哪一种,我得到了这个错误:
[1] passport.use(User.createStrategy());
[1] ^
[1] TypeError: User.createStrategy is not a function
这个错误:
[1] passport.use(new LocalStrategy(User.authenticate()));
[1] ^
[1] TypeError: User.authenticate is not a function
我试着在谷歌上搜索了很多解决方案,但似乎找不到任何相关的东西。
编辑:据我所知,./models/user.ts
中的userSchema.plugin(passportLocalMongoose);
应该将函数添加到模型中。配置Passport/Passport-Local和简化Passport/Passport-Local配置显示了如何设置它,但它似乎不适合我。
相关依赖版本:
"dependencies": {
"cookie-parser": "^1.4.3",
"express": "^4.14.0",
"express-session": "^1.15.3",
"mongoose": "^4.7.2",
"passport": "^0.3.2",
"passport-local": "^1.0.0",
"passport-local-mongoose": "^4.0.0",
"session-file-store": "^1.0.0",
"typescript": "~2.2.0",
},
"devDependencies": {
"ts-node": "~2.0.0",
},
./models/user.ts
import * as mongoose from 'mongoose';
const passportLocalMongoose = require('passport-local-mongoose');
const userSchema = new mongoose.Schema({
email: String,
password: String,
displayname: String,
groups: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Group'
}]
});
userSchema.plugin(passportLocalMongoose, {
usernameField: 'email'
});
const User = mongoose.model('User', userSchema);
export default User;
./app.ts的相关部分
import * as express from 'express';
import * as cookieParser from 'cookie-parser';
import * as session from 'express-session';
const FileStore = require('session-file-store')(session);
import * as mongoose from 'mongoose';
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const app: express.Express = express();
const cookieSecret = 'asdf';
app.use(cookieParser(cookieSecret));
app.use(session({
secret: cookieSecret,
resave: false,
saveUninitialized: false,
store: new FileStore()
}));
// Configure passport middleware
app.use(passport.initialize());
app.use(passport.session());
// Configure passport-local to use User model for authentication
const User = require('./models/user');
passport.use(User.createStrategy());
// Alternatively: passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
完整./app.ts
import * as express from 'express';
import * as bodyParser from 'body-parser';
import * as cookieParser from 'cookie-parser';
import * as session from 'express-session';
const FileStore = require('session-file-store')(session);
import * as path from 'path';
import * as logger from 'morgan';
import * as mongoose from 'mongoose';
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
// import index from './routes/index';
// import users from './routes/users';
const app: express.Express = express();
// // view engine setup
// app.set('views', path.join(__dirname, 'views'));
// app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
// app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
const cookieSecret = '';
app.use(cookieParser(cookieSecret));
app.use(session({
secret: cookieSecret,
resave: false,
saveUninitialized: false,
store: new FileStore()
}));
app.use(express.static(path.join(__dirname, 'public')));
// Configure passport middleware
app.use(passport.initialize());
app.use(passport.session());
// Configure passport-local to use User model for authentication
const User = require('./models/user');
passport.use(User.createStrategy());
// Alternatively: passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
// app.use('/', index);
// app.use('/users', users);
// routes
const routeModules = require('require-all')({
dirname: __dirname + '/routes',
filter: (filename: string) => {
filename = filename.toLowerCase();
if ((filename.endsWith('.ts') && !filename.endsWith('.spec.ts'))
|| (filename.endsWith('.js') && !filename.endsWith('.spec.js'))) {
return filename.substr(0, filename.length - 3);
}
},
map: name => '/' + name
});
function resolve(root: string, modules): void {
for (const name of Object.keys(modules)) {
if (!name.startsWith('/')) {
return;
}
const module = modules[name];
if (module.default && module.default.route) {
console.log(`Add router ${root + name}`);
const router = module.default as express.Router;
app.use(root, router);
} else {
resolve(root + name, module);
}
}
}
resolve('', routeModules);
// Default to main page, angular route takes over
app.use((req, res) => {
res.sendFile(path.join(__dirname, 'public/index.html'));
});
// // catch 404 and forward to error handler
// app.use((req, res, next) => {
// var err = new Error('Not Found');
// err['status'] = 404;
// next(err);
// });
// // error handlers
// // development error handler
// // will print stacktrace
// if (app.get('env') === 'development') {
// app.use((error: any, req, res, next) => {
// res.status(error['status'] || 500);
// res.render('error', {
// message: error.message,
// error
// });
// });
// }
// // production error handler
// // no stacktraces leaked to user
// app.use((error: any, req, res, next) => {
// res.status(error['status'] || 500);
// res.render('error', {
// message: error.message,
// error: {}
// });
// return null;
// });
export default app;
// Connect to MongoDB
mongoose.connect('mongodb://localhost/test');
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', () => {
console.log('MongoDB connected');
});
8条答案
按热度按时间gkl3eglg1#
像这样更新你的user.ts文件:
对我很有效
bnl4lu3b2#
很抱歉晚才回答。我找到解决的办法了。
taor4pac3#
我遇到了同样的问题,我只是通过添加来解决它:
这段代码在userSchema声明下,在用户模式模型声明**之前。
示例:
f1tvaqid4#
如果我能正确理解的话,这仅仅是由未解析的类型引起的,而不是真实的的代码错误。
去解决它-
1.在项目中包含类型定义文件,它将扩展mongoose中的类型:https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/passport-local-mongoose/index.d.ts
1.在
app.ts
中,从mongoose
导入所需的类型(注意PassportLocalModel
来自上面的定义文件):import { Document, PassportLocalModel } from "mongoose";
1.现在可以将更新后的类型强制转换为
User
:(User as PassportLocalModel<Document>).createStrategy()
(User as PassportLocalModel<Document>).authenticate()
xzv2uavs5#
为了解决这个问题,我已经检查了他们是如何实际测试类型的-https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/passport-local-mongoose/passport-local-mongoose-tests.ts用法变得相当清楚。
以下是我工作的(请注意PassportLocalDocument,PassportLocalSchema,PassportLocalModel的用法):
sqyvllje6#
对我很有效。尝试使用此格式:
slwdgvem7#
31moq8wy8#
只需在创建模型之前添加userSchema.plugins,如下所示:
然后使用模型。对我来说效果很好。