Skip to content

Instantly share code, notes, and snippets.

@slawekzachcial
Created June 2, 2019 22:10
Show Gist options
  • Save slawekzachcial/3fe7e1f3a4b0f92aea08021b32b108c8 to your computer and use it in GitHub Desktop.
Save slawekzachcial/3fe7e1f3a4b0f92aea08021b32b108c8 to your computer and use it in GitHub Desktop.
GitHub authentication in ExpressJS app.
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