Node.js OAuth 2.0 API with public and secure endpoints and delegated authorization. Instructions are available below for setting up this API using Auth0 as the authorization server for issuing access tokens.
- Node.js with npm, Node >= 6.9.0, npm >= 3
- Free Auth0 account
Install the server dependencies with npm or yarn:
$ npm install
# or yarn install
- Go to the Auth0 Dashboard - APIs section and click the "+ Create API" button.
- Give your API a name like
Secure Dino API
and enter an identifier. The identifier will be the audience claim for access tokens to call this API. The identifier should behttps://secure-dino-api
. - Go to the Scopes tab of your API's settings. Add
read:dino-details
andwrite:dino-fav
as scopes.
- Go to the Auth0 Dashboard - Rules section and create a new Rule. Choose the Empty Rule template. (Alternatively, you could choose the Set roles to a user template and modify it according to your needs.)
- Give your rule a name.
Set user roles and add to tokens
would be appropriate. - Enter the following code in the Rule editor, replacing
{YOUR_FULL_EMAIL_HERE}
with your own email address:
function (user, context, callback) {
// Make sure the user has verified their email address
if (!user.email || !user.email_verified) {
return callback(new UnauthorizedError('Please verify your email before logging in.'));
}
user.app_metadata = user.app_metadata || {};
var addRolesToUser = function(user, cb) {
if (user.email && user.email === '{YOUR_FULL_EMAIL_HERE}') {
cb(null, ['editor']);
} else {
cb(null, []);
}
};
addRolesToUser(user, function(err, roles) {
if (err) {
callback(err);
} else {
user.app_metadata.roles = roles;
auth0.users.updateAppMetadata(user.user_id, user.app_metadata)
.then(function(){
var namespace = 'https://secure-dino-api/roles';
var userRoles = user.app_metadata.roles;
context.idToken[namespace] = userRoles;
context.accessToken[namespace] = userRoles;
callback(null, user, context);
})
.catch(function(err){
callback(err);
});
}
});
}
- Open the
.env.sample
file. - Replace the
ISSUER_BASE_URL
value with your Auth0 domain withhttps://
in front of it (e.g.,https://{your-tenant}.auth0.com
). - Enter the API identifier as the
ALLOWED_AUDIENCES
value. This should behttps://secure-dino-api
(as specified in the Auth0 setup above). - Replace the
ROLES_CLAIM_NAMESPACE
value with your collision-resistant custom JWT roles claim namespace. If you copied the rule code from the section above, this will behttps://secure-dino-api/roles
. - Remove the
.sample
extension to activate the file.
To start the server locally, run the following command from the root of the folder containing your server.js
file:
$ npm start
# nodemon server
There are several endpoints available:
This endpoint is public. It returns an array of objects with the following type:
[
{
name: string,
pronunciation: string,
favorite?: boolean
},
{...}
]
This endpoint requires authorization with an access token. It returns a dinosaur object with the following type:
{
name: string;
pronunciation: string;
meaningOfName: string;
diet: string;
length: string;
period: string;
mya: string;
info: string;
favorite?: boolean;
}
Delegated access is available with the read:dino-details
scope for access tokens issued by the ISSUER_BASE_URL
you specify in the .env
file (rename .env.sample
and add your configuration).
This endpoint requires authorization with an access token. A post body
must be sent with the request containing the name of the dinosaur that should be marked as a favorite.
The dinosaur favorite property will be toggled and the dinosaur's full details will be returned:
{
name: string;
pronunciation: string;
meaningOfName: string;
diet: string;
length: string;
period: string;
mya: string;
info: string;
favorite?: boolean;
}
The dinosaur simplified listing will also be updated to reflect favoriting activity. Changes will persist in the local user's instance until the local Node server is restarted. (Data is not stored anywhere outside of the JavaScript implementation, so it will not persist for multiple users or across sessions.)
Delegated access is available with the write:dino-fav
scope for access tokens issued by the ISSUER_BASE_URL
you specify in the .env
file (rename .env.sample
and add your configuration).
A user role of 'editor'
is also required in an array of roles contained in a custom claim in the access token. (Instructions for doing so are here.) You can add custom claims to your Auth0 tokens using Auth0 Rules. You should set the collision-resistant namespace for your rule in the .env
file.
For testing these endpoints, a Postman collection is available here. The collection uses a variable for authorization. The variable is called access_token
, and you should update the value of this variable with an appropriate access token (acquired via your authorization server) to test the secured endpoints.
This project is licensed under the MIT license. See the LICENSE file for more info.