Skip to content

Instantly share code, notes, and snippets.

@dominictobias
Created January 6, 2019 23:27
Show Gist options
  • Select an option

  • Save dominictobias/6a30ede63012fb99c07896d35f554909 to your computer and use it in GitHub Desktop.

Select an option

Save dominictobias/6a30ede63012fb99c07896d35f554909 to your computer and use it in GitHub Desktop.
NodeJS OAuth from scratch (using GitHub as an example)
// Packages like PassportJS and useless diagrams online make OAuth seem complicated to implement, but in reality it's simple...
const got = require('got');
const jwt = require('jsonwebtoken');
const querystring = require('querystring');
const mins = min => 1000 * 60 * min;
// 1. Direct users browser to this url.
app.get('auth/github', (req, res) => {
const csrfState = Math.random().toString(36).substring(7);
res.cookie('csrfState', csrfState, { maxAge: mins(1) });
const query = {
scope: 'read:user',
client_id: 'YOUR_APP_CLIENT_ID',
state: csrfState,
};
res.redirect(`https://github.com/login/oauth/authorize?${querystring.stringify(query)}`);
});
// 2. OAUTH provider is configured to return here after user accepts.
app.get('auth/github/callback', async (req, res) => {
const { code, state } = req.query;
const { csrfState } = req.cookies;
if (state && csrfState && state !== csrfState) {
res.msg(422, `Invalid state: ${csrfState} != ${state}`);
return;
}
// 3. Make POST back to oauth provider with the `code` and receive an access token back.
const response = await got.post('https://github.com/login/oauth/access_token', {
json: true,
body: {
client_id: 'YOUR_APP_CLIENT_ID',
client_secret: 'YOUR_APP_CLIENT_SECRET',
code,
state,
},
});
// 4. Fetch user email with accessToken from provider (response.body.access_token).
const email = 'emailgivenbyprovider@blah.com';
// 5. Get or create user on your database, return the user ID:
// Note that you don't necessary need to save the access token.
const user = { id: '123', email };
// 6. Create a JSON web token.
const token = jwt.sign({ id: user.id }, 'YOUR_MADE_UP_SECRET_KEY', { expiresIn: '30 days' });
// 7. Redirect to your app, your app should save the token to make with requests, and redirect
// the user to e.g. /dashboard.
res.redirect(`https://your-spa-app/auth?token=${jwtToken}`);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment