For some reason, OAuth always seems overly complicated. Documentation stinks and errors are vague. Abstractions like Passport.js add a mountain of complication while barely reducing friction. Does it have to be this hard? Actually, no.
Facebook authentication for NodeJS is actually pretty easy.
Step 1. Get Credentials
First you need credentials. Buckle up because this is really the only challenging part.
Go find or register a new Facebook app. Then enable the Facebook Login product. It will try to take you through a Quickstart, but skip that – click the Settings button instead and you’ll see this screen:

You don’t need to change anything except “Valid OAuth Redirect URIs”. This is the URL that facebook will redirect your user to after logging in. Facebook will automatically allow localhost urls for testing, so enter your production url. I made up the /facebook/callback
part as you’ll see below. Facebook will also append a code
parameter in the query string.
Now click Settings > Basic on the left. You should now have your App ID, App Secret, and Redirect URL.
Step 2. Send Them To The Login Page
We’ll use the query-string
package on npm to create the login url.
npm install --save query-string axios
Now create an express route. The user goes to /facebook/login
and gets redirected to the login page:
import app from ???;
import * as qs from 'query-string';
const settings = {
appId: '*****************',
appSecret: '************************',
redirectUrl: 'http://localhost:7777/facebook/callback',
};
app.get('/facebook/login', async (req, res) => {
const params = qs.stringify({
client_id: settings.appId,
redirect_uri: settings.redirectUrl,
scope: ['email'].join(','),
response_type: 'code',
auth_type: 'rerequest',
display: 'popup',
});
const url = `https://www.facebook.com/v4.0/dialog/oauth?${params}`;
res.redirect(url);
});
Pretty simple. See all available query string options here. We’re just loading email
but see all scopes here. Consider using the dotenv package for a better way to store sensitive settings.
Step 3. Setup The Callback
So you sent the user to the login page, now Facebook sends them back with a code parameter. You need to use that code to find the user’s email:
app.get('/facebook/callback', async (req, res) => {
// Get the login code
const { code } = req.query;
// Fetch the access token
const tokenResponse = await axios({
url: 'https://graph.facebook.com/v4.0/oauth/access_token',
method: 'get',
params: {
client_id: settings.appId,
client_secret: settings.appSecret,
redirect_uri: settings.redirectUrl,
code,
},
});
const { access_token } = tokenResponse.data;
// Fetch the email
const meResponse = await axios({
url: 'https://graph.facebook.com/me',
method: 'get',
params: {
fields: ['email'].join(','), // matches scope
access_token,
},
});
const { email } = meResponse.data;
// TODO: login with email
res.redirect('/');
});
So we use the code to get the token. Then use the token to get the email. You’ll need to implement the TODO portion – use the email address to find or create a user, then sign them in.
And that’s it! My entire facebook authentication implementation is 50 lines of code and very readable. Amazing!
See the complete facebook-auth-routes.js source code at: https://gist.github.com/bendytree/67ec68628f808b88aa3136bb1e2e7f97