Reputation: 1614
config/passport.ts
/// <reference path='../typings/index.d.ts' />
import * as passport from 'passport';
import { User } from '../models/user';
import * as config from './main';
import { Strategy as JwtStrategy, ExtractJwt } from 'passport-jwt';
import { Strategy as LocalStrategy } from 'passport-local';
const localOptions = { usernameField: 'email' };
// Setting up local login strategy
const localLogin = new LocalStrategy(localOptions, function(email, password, done) {
User.findOne({ email: email }, function(err, user) {
if(err) { return done(err); }
if(!user) { return done(null, false, { message: 'Your login details could not be verified. Please try again.' }); }
//test instead of user.comparePassword
user.schema.methods.comparePassword(password, function(err, isMatch) {
if (err) { return done(err); }
if (!isMatch) { return done(null, false, { message: "Your login details could not be verified. Please try again." }); }
return done(null, user);
});
});
});
const jwtOptions = {
// Telling Passport to check authorization headers for JWT
jwtFromRequest: ExtractJwt.fromAuthHeader(),
// Telling Passport where to find the secret
secretOrKey: config.secret
};
// Setting up JWT login strategy
const jwtLogin = new JwtStrategy(jwtOptions, function(payload, done) {
User.findById(payload._id, function(err, user) {
if (err) { return done(err, false); }
if (user) {
done(null, user);
} else {
done(null, false);
}
});
});
passport.use(jwtLogin);
passport.use(localLogin);
router.ts
import * as AuthenticationController from './controllers/authentication';
import * as express from 'express';
import * as passport from 'passport';
import * as passportService from './config/passport';
// Middleware to require login/auth
const requireAuth = passport.authenticate('jwt', { session: false });
const requireLogin = passport.authenticate('local', { session: false });
// Constants for role types
const REQUIRE_ADMIN = "Admin";
const REQUIRE_OWNER = "Owner";
const REQUIRE_CLIENT = "Client";
const REQUIRE_MEMBER = "Member";
export function router(app) {
// Initializing route groups
const apiRoutes = express.Router();
const authRoutes = express.Router();
// Registration route
authRoutes.post('/register', AuthenticationController.register);
// Login route
authRoutes.post('/login', requireLogin, AuthenticationController.login);
// Set auth routes as subgroup/middleware to apiRoutes
apiRoutes.use('/auth', authRoutes);
// Set url for API group routes
app.use('/api', apiRoutes);
};
index.ts
/// <reference path="./typings/index.d.ts" />
// Importing Node modules and initializing Express
import * as express from 'express';
import * as logger from 'morgan';
import * as config from './config/main';
import * as bodyParser from 'body-parser';
import * as mongoose from 'mongoose';
import { router } from './router';
export const app = express();
const server = app.listen(config.port);
console.log(`Your server is running on port ${config.port}.`);
app.use(logger('dev'));
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, Access-Control-Allow-Credentials");
res.header("Access-Control-Allow-Credentials", "true");
next();
});
//DB connection
mongoose.connect(config.database);
//Body parsing
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
router(app);
And the error:
POST /api/auth/login 500 4.796 ms - 1947
Error: Unknown authentication strategy "local"
at attempt (/Users/pumz/closeloop/app/server/node_modules/passport/lib/middleware/authenticate.js:173:37)
at authenticate (/Users/pumz/closeloop/app/server/node_modules/passport/lib/middleware/authenticate.js:349:7)
at Layer.handle [as handle_request] (/Users/pumz/closeloop/app/server/node_modules/express/lib/router/layer.js:95:5)
at next (/Users/pumz/closeloop/app/server/node_modules/express/lib/router/route.js:131:13)
at Route.dispatch (/Users/pumz/closeloop/app/server/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/Users/pumz/closeloop/app/server/node_modules/express/lib/router/layer.js:95:5)
at /Users/pumz/closeloop/app/server/node_modules/express/lib/router/index.js:277:22
at Function.process_params (/Users/pumz/closeloop/app/server/node_modules/express/lib/router/index.js:330:12)
at next (/Users/pumz/closeloop/app/server/node_modules/express/lib/router/index.js:271:10)
at Function.handle (/Users/pumz/closeloop/app/server/node_modules/express/lib/router/index.js:176:3)
at router (/Users/pumz/closeloop/app/server/node_modules/express/lib/router/index.js:46:12)
at Layer.handle [as handle_request] (/Users/pumz/closeloop/app/server/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/Users/pumz/closeloop/app/server/node_modules/express/lib/router/index.js:312:13)
at /Users/pumz/closeloop/app/server/node_modules/express/lib/router/index.js:280:7
at Function.process_params (/Users/pumz/closeloop/app/server/node_modules/express/lib/router/index.js:330:12)
at next (/Users/pumz/closeloop/app/server/node_modules/express/lib/router/index.js:271:10)
I believe everything is well configured, I got no compilation errors, and the register works as expected.
I've seen some require('passport-local')(passport)
that solves it, but it's not working. Nor changing the authentication method to local-login
Upvotes: 0
Views: 1662
Reputation: 6432
I know I'm late but I'll provide my advice anyway in case someone else who needs it found their way here.
According to the www.typescriptlang.org:
Though not recommended practice, some modules set up some global state that can be used by other modules. These modules may not have any exports, or the consumer is not interested in any of their exports. To import these modules, use:
import "./my-module.js";
In your case this should do:
import './config/passport';
All the content of passport.ts
will be executed.
Upvotes: 0
Reputation: 3129
import * as passportService from './config/passport';
TypeScript will elide that import as you are not using anything config/passport is exporting (you're not exporting anything at all from that module actually) in the value position. See https://github.com/Microsoft/TypeScript/issues/2812 and similar.
If you look at the transpiled output for router.ts you will see that it is indeed missing require('./config/passport'). The fix is to export something from that module and then reference it -- maybe initialize the passport authentication strategies in an exported init() function.
Upvotes: 1