Since the function has no return value - how can I identify what's causing the function to fail. I have the following code:
function test(req : IncomingMessage, res :ServerResponse, next:(err:any)=>void) {
passport.authenticate('google', {scope:['https://www.googleapis.com/auth/userinfo.email']})(req, res,next);
//how do I get details here
}
I mean I know it's failing since the next handler in line is not called but how do I get more detailed information?
This function is instanced like following:
export const usersRouter = express
.Router()
.post('/googleLogin', test, async (req, res) => {
const user: User = req.user;
if (!user) {
res.send(401);
}
// const token = getJwtToken(user._id.toHexString());
// res.send({ token });
})
An authentication workflow such as this (oauth / openid) involves several steps.
redirect the user to google's authentication service
google authenticates the user and ask confirmation from the user to accept/reject your service
if the user accepts google redirects the user back to your service's callback uri with an access code.
your server (not the user's browser) request an access/refresh token to google's servers using your app's id and secret (as issued from google when registering the app) and the access code received before.
if all is good, google will issue an access/refresh token to your service that you will have to associate to an user in your side (either an existing user using this google id, or create a new user as in sign up, or associate to an already logged user as in connect account).
In order to inspect what's going on, you can check each step on your side:
This will just redirect your user to google's authentication service
app.get('/auth/google',
passport.authenticate('google', {
scope: ['https://www.googleapis.com/auth/userinfo.email']
});
you will use this endpoint from your user interface, something like :
<a href="/auth/google">Connect with google</a>
Once google authenticates you user and redirects back your user to your service, this is the endpoint that the user will be redirected to:
app.get('/auth/google/callback',
(req, res, next) => {
// You can inspect google's redirection here
return next();
},
passport.authenticate('google', { failureRedirect: '/login' }),
function(req, res) {
res.redirect('/');
});
At this point passport will carry on the authentication flow to request an access/refresh token from google.
Your strategy definition's callback is invoked when your server is requesting an access/refresh token from google:
passport.use(new GoogleStrategy({
consumerKey: GOOGLE_CONSUMER_KEY,
consumerSecret: GOOGLE_CONSUMER_SECRET,
callbackURL: "http://www.example.com/auth/google/callback"
},
function(token, tokenSecret, profile, done) {
// you can debug google's response here (this is from your server's request)
User.findOrCreate({ googleId: profile.id }, function (err, user) {
return done(err, user);
});
}
));
Hope this helps.
Maybe with a custom callback. (From the documentation.)
In this example, note that authenticate() is called from within the route handler, rather than being used as route middleware. This gives the callback access to the req and res objects through closure.
app.get('/googleLogin', function(req, res, next) {
passport.authenticate('google', function(err, user, info) {
if (err) { return next(err); }
if (!user) { return res.redirect('/login'); }
req.logIn(user, function(err) {
if (err) { return next(err); }
return res.redirect('/users/' + user.username);
});
})(req, res, next);
});