0
votes

I have set up the spotify passport strategy with a mongo db to save the user profile, access and refresh tokens. But apart from the initial auth route and then the callback url, do I need to pass passport.authenticate as a callback to every route? Or am I supposed to have a custom middleware that checks if the cookie-session module still has req.user on the request? I see these as two possibilities. Which is the correct one? I know that on the cookie side, it will eventually expire and the /auth route will need to be called again.

I have made a middleware function that checks the user property of the request object. But am not sure how to test it. Perhaps reducing the cookie expiration time and check req.user is false.

passport.serializeUser((user, done) => {
    done(null, user.id);
});

passport.deserializeUser((id, done) => {
    User.findById(id)
        .then((user) => {
            done(null, user);
        });
});

passport.use(new SpotifyStrategy({
    clientID: keys.spotifyClientID,
    clientSecret: keys.spotifyClientSecret,
    callbackURL: '/auth/spotify/callback',
    proxy: true
}, async (accessToken, refreshToken, profile, done) => {

    const spotifyId = profile.id
    const name = profile.displayName
    const email = profile.emails[0].value

    const existingUser = await User.findOne({ spotifyId: profile.id });

    if (existingUser) {
        return done(null, existingUser);
    }

    const user = await new User({ spotifyId, name, accessToken, refreshToken}).save();

    done(null, user);
}));

Check the cookie middleware:

module.exports = isAuthenticated = (req, res, next) => {

if (req.user) {
    return next();
}

return res.redirect('/auth/spotify');
}
Example route:


module.exports = (app) => {

app.get('/api/spotify/playlists', passport.authenticate('spotify'), 
  (req, res) => {

console.log('got here')
console.log(req.user);

 //return playlists
});
 }

1

1 Answers

1
votes

You can create a middleware which will check if the user is authenticated or not, and add that middleware to your routes.

Passport runs deserializeUser everytime a request is called, and it stores the authenticated user in req.user. The middleware will check if req.user exists, and if it exits it means the user is logged in and authenticated, and the request can be allowed to proceed.

You dont need to use passport.authenticate('spotify') with every request, you only need it at the time of login( or registration).

Middleware can be added like this:

function isAuthenticated(req, res, next) {
    if (req.user) {
        next();
    } else {
        res.redirect('/login');
    }
}

app.get('/api/spotify/playlists', isAuthenticated, 
  (req, res) => {

console.log('got here')
console.log(req.user);

 //return playlists
});

i hope this works out for you.