Reputation: 18461
I have the following code, but my passport-jwt strategy is not being triggered:
Authenticator.js
import passport from "passport";
import passportJWT from "passport-jwt";
const ExtractJwt = passportJWT.ExtractJwt;
const JwtStrategy = passportJWT.Strategy;
export const set = app => {
const opts = {
secretOrKey: secret,
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken()
};
let strategy = new JwtStrategy(opts, (payload, done) => {
console.log("Strategy called");
console.log(payload);
// Check user and company
let user = getUserById(payload);
if (!user) return done(new Error("User not found"), false);
let context = {
id: user.id,
username: user.username,
name: user.name
};
return done(null, context);
});
passport.use(strategy);
console.log("Initializing passport");
app.use(passport.initialize());
};
Server.js
import express from "express";
import bodyParser from "body-parser";
import mongoose from "mongoose";
import * as routes from "./routes";
import * as authenticator from "./authenticator";
mongoose.Promise = global.Promise;
const app = express();
app.set("port", process.env.API_PORT || 3001);
app.disable("x-powered-by");
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
const mongoUri = process.env.MONGO_URI || "mongodb://localhost/db";
mongoose.connect(mongoUri);
authenticator.set(app);
routes.set(app);
app.listen(app.get('port'), () => {
console.log(`Find the server at: http://localhost:${app.get('port')}/`); });
Routes.js:
import express from "express";
import passport from "passport";
import path from "path";
import appGraphQL from "graphql/src/graphql";
import * as authenticator from "./authenticator";
const router = express(router);
export const set = app => {
app.use(
"/graphql",
passport.authenticate("jwt", { session: false }),
appGraphQL()
);
};
Fetching from client:
function fetchQuery(operation, variables, cacheConfig, uploadables) {
const token = sessionStorage.getItem('jwtToken');
return fetch(SERVER, {
method: 'POST',
headers: {
Authorization: 'Bearer ' + token,
Accept: 'application/json',
'Content-type': 'application/json'
},
body: JSON.stringify({
query: operation.text,
variables
})
})
.then(response => {
if (response.status === 401)
throw new Error('Error401:Unauthorized');
else return response.json();
})
.catch(error => {
throw new Error(
'(environment): Error while fetching server data. ' + error
);
});
}
How can I find out why passport is not calling the authenticator callback strategy?
Upvotes: 0
Views: 1031
Reputation: 9629
I know this question is about javascript though I came here in search for an answer for Typescript in the TSeD.io framework where similarly the passport-jwt strategy was not being triggered.
The answer for me was that the (request, response)
needs to be passed in the Passport.Authenticate()
call, something that doesn't need to be done when it is being used as middleware within an Express endpoint. Like this as per login
and signup
on https://tsed.io/tutorials/passport.html#local-strategy.
I realise that this is necessary whenever the .authenticate()
call is being done outside of an express endpoint. For example also in https://medium.com/front-end-hacking/learn-using-jwt-with-passport-authentication-9761539c4314. The reason is because Middleware called in an express endpoint will automagically be passed (request, respone)
.
@Controller("/passport")
export class PassportCtrl {
@Post("/login")
async login(@Required() @BodyParams("email") email: string,
@Required() @BodyParams("password") password: string,
@Req() request: Express.Request,
@Res() response: Express.Response) {
return new Promise<IUser>((resolve, reject) => {
Passport
.authenticate("login", (err, user: IUser) => {
if (err) {
reject(err);
}
request.logIn(user, (err) => {
if (err) {
reject(err);
} else {
resolve(user);
}
});
})(request, response, () => {
});
});
}
}
Upvotes: 3