Created
June 2, 2019 22:10
-
-
Save slawekzachcial/3fe7e1f3a4b0f92aea08021b32b108c8 to your computer and use it in GitHub Desktop.
GitHub authentication in ExpressJS app.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const cookieSecret = process.env.COOKIE_SECRET || 'secret' | |
const cookieName = process.env.COOKIE_NAME || 'GitHubAuthenticated' | |
const githubHost = process.env.GHE_HOST || 'https://github.com' | |
const githubApiUrl = process.env.GHE_API_URL || 'https://api.github.com' | |
const clientId = process.env.CLIENT_ID | |
const clientSecret = process.env.CLIENT_SECRET | |
const userAgent = 'My-App' | |
const express = require('express') | |
const app = express() | |
const port = 3000 | |
const cookieParser = require('cookie-parser') | |
const querystring = require('querystring') | |
const request = require('request-promise-native') | |
app.use(cookieParser(cookieSecret)) | |
app.use('/protected', function (req, res, next) { | |
const ghAuthCookie = req.signedCookies[cookieName] | |
console.log(`Cookie: ${ghAuthCookie}`) | |
if (!ghAuthCookie) { | |
const authorizeRequest = { | |
client_id: clientId, | |
redirect_uri: `${req.protocol}://${req.host}:${port}/oauth/callback`, | |
state: `${req.protocol}://${req.host}:${port}${req.originalUrl}` | |
} | |
console.log(`Authorization request: ${JSON.stringify(authorizeRequest)}`) | |
res.redirect(`${githubHost}/login/oauth/authorize?${querystring.stringify(authorizeRequest)}`) | |
} | |
else { | |
next() | |
} | |
}) | |
app.get('/oauth/callback', async (req, res) => { | |
console.log(`Callback params: ${JSON.stringify(req.query)}`) | |
try { | |
const code = req.query.code | |
const state = req.query.state | |
const accessTokenRequest = { | |
client_id: clientId, | |
client_secret: clientSecret, | |
code: code, | |
state: state | |
} | |
const accessToken = await request({ | |
method: 'POST', | |
url: `${githubHost}/login/oauth/access_token`, | |
headers: { | |
'Accept': 'application/json', | |
'User-Agent': userAgent | |
}, | |
form: accessTokenRequest, | |
json: true | |
}) | |
console.log(`Access Token: ${JSON.stringify(accessToken)}`) | |
const user = await request({ | |
method: 'GET', | |
url: `${githubApiUrl}/user`, | |
headers: { | |
'Authorization': `token ${accessToken.access_token}`, | |
'User-Agent': userAgent | |
}, | |
json: true | |
}) | |
console.log(`User: ${user.login}`) | |
res.cookie(cookieName, (new Date()).getTime(), { signed: true }) | |
res.redirect(state) | |
} catch (error) { | |
console.log(error) | |
res.status(500).send(error) | |
} | |
}) | |
app.get('/', (req, res) => res.send('Hello World!')) | |
app.get('/protected', (req, res) => res.send('This page is protected by GitHub')) | |
app.get('/protected/x', (req, res) => res.send('This page is also protected by GitHub')) | |
app.listen(port, () => console.log(`Listening on port ${port}`)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment