Authenticate Apollo GraphQL API with Passport Facebook
Asked Answered
S

0

8

I have a client server and an API, both using Apollo. When the user logs in with Facebook I want to send a token to my client server which will then be appended to the headers of every request made to the API. Without using sessions.

Here's how the API looks, this generates the token successfully when a user logs in with Facebook (I'm also checking for users in a database behind the scenes).

// API running on port 3010
app.use(expressJwt({
    secret: authConfig.jwt.secret,
    credentialsRequired: false,
    getToken: req => req.cookies.id_token,
}));
app.use(passport.initialize());
app.get('/login/facebook',
    passport.authenticate('facebook', { scope: ['email'], session: false }),
);

app.get('/login/facebook/return',
    passport.authenticate('facebook', { failureRedirect: 'http://localhost:3000/login', session: false }),
    (req, res) => {
        const expiresIn = 60 * 60 * 24 * 1; // 1 day
        const token = jwt.sign(req.user, authConfig.jwt.secret, { expiresIn });
        res.redirect(`http://localhost:3000?token=${token}`); // Redirect to client and append token to param
    },
);

My question is, how do I now hand this token to the client securely? I've read this and this, which led me to passing the token in a param, but I'm not sure if what I'm doing is secure.

Here's how I'm getting it on the client side:

const token = getURLParameterByName('token');
if (token) {
    localStorage.setItem('token', token);
}

networkInterface.use([{
    applyMiddleware(req, next) {
        if (!req.options.headers) {
            req.options.headers = {};   // Create the header object if needed.
        }

        // Get the authentication token from local storage if it exists
        const localToken = localStorage.getItem('token')
        req.options.headers.authorization = localToken ? `Bearer ${localToken}` : null;
        next();
    },
}]);

After this, using it in the API:

app.use('/graphql', apolloExpress(req => {
    let token;
    if (req.headers.authorization) {
        token = req.headers.authorization;
        console.log(token);
    }

    return {
        schema: executableSchema,
        context: {
            token,
        },
    };
}));
Sapers answered 12/12, 2016 at 22:33 Comment(1)
This question is explained in https://mcmap.net/q/438678/-facebook-passport-with-jwtEffectuate

© 2022 - 2024 — McMap. All rights reserved.