OAuth is a protocol for allowing one application controlled access to a user’s account on another application. It is commonly used for two purposes:
In this article, I’ll describe how to build a minimal OAuth server with Node.js and Express, no OAuth modules allowed. The only exception is Matt Mueller’s excellent oauth-open
package for displaying an OAuth popup on the client side to verify that we actually have a working OAuth setup.
Your standard web OAuth 2.0 flow has 3 steps:
code
parameter from the query string, and makes a POST request to the authorizing app’s server with the access code. The authorizing app’s server verifies the access code and sends back an access token your app can use for authorization going forward.For the purposes of this example, there’s 2 components involved in the OAuth flow:
Note that this code is meant as a minimal didactic example. The below code is most definitely not a production-grade OAuth authorization server. Don’t copy/paste it into your prod app.
First, let’s take a look at the client app to see what endpoints the authorization server needs to implement. The client app server’s entry point is a simple static server listening on port 3000:
'use strict';
const express = require('express');
run().catch(err => console.log(err));
async function run() {
const app = express();
app.use(express.static('./'));
await app.listen(3000);
console.log('Listening on port 3000');
}
The client app has one file, index.html
. This file is responsible for opening an OAuth dialog, exchanging the auth code for an access token, and making an HTTP request to a secure endpoint using the access token as authorization. The auth server will run on http://localhost:3001
.
<html>
<body>
<div id="content"></div>
<script type="text/javascript" src="https://codebarbarian-images.s3.amazonaws.com/open.dist.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script type="text/javascript">
// Step 1: open an OAuth dialog
oauthOpen('http://localhost:3001/oauth-dialog.html', async (err, code) => {
// Step 2: exchange the code for an access token
const resToken = await axios.post('http://localhost:3001/token', { code: code.code });
// Step 3: use the access token to make a request to a secure
// endpoint and display some data
const res = await axios.get('http://localhost:3001/secure', {
headers: { authorization: resToken.data['access_token'] }
});
document.querySelector('#content').innerHTML =
`The secret answer is ${res.data.answer}`;
});
</script>
</body>
</html>
#node #express #oauth #secuirty #programming