Creating an OAuth2 server is not a task that should be taken lightly. There are many security loopholes that could be exploited, and regular examinations are critical to handle possible vulnerabilities.
Auth is an authentication microservice based on the OAuth2 identity delegation protocol.
Identity delegation allows a resource provider (such as Facebook) to be informed of the fact that a resource owner (a particular user in Facebook) allows a third-party (some application other than Facebook) to access and/or change the data belonging to the resource owner. OAuth 2 is becoming the standard when it comes to the security of APIs and many famous web apps have already implemented this authorization mechanism – such as Facebook, LinkedIn, Google and PayPal.
We also use JSON Web Tokens as our identity token format.
A JWT are basically a signed JSON documents which can optionally be encrypted. These JWT are send in the HTTP header as bearer tokens to the resource server so that it can verify the authentication and authorization of the client request. This is possible because the resource server and the authorization server have established a trust relationship before via a shared secret or a public key. In that way the resource server can validate the signature of the JSON web token.
There are two types of supported modes of authentication: Basic (username+password) and Third-Party (fb, google) which is explained below.
For basic authentication with username and password, we use the resource owner password flow / OAuth2 Password Credentials grant type. and chose node-oauth2-server to build our server.
Using this grant type, applications can directly get an access token but would have to know the username and the password of the resource owner.
Clients has to make a POST request to /auth/basic
with a HTTP Basic Auth header with contents being the app’s client id
and client secret
encoded in base64
and separated by a :
(Authorization: Basic CLIENT_ID:CLIENT_SECRET
). The app must also provide some POST data with the request – a grant_type
of password
and the username
and password
of the resource owner who is delegating access.
For example:
curl localhost:9999/oauth/basic -H “Authorization: Basic cEUxUXo3TFNPelRQU2JQNDpLYVhTMkxmbk9VeFhqVHE1aWlrb3ozTElnblBpTTg=” –data “grant_type=password&username=tester2&password=tester2”
A sample response would be:
{
“token_type”:”bearer”,
”access_token”:”fc415000a8cf06ad2688b1421fa64f6ab24c44de”,
”expires_in”:86400
}
These tokens can expire, and clients should re-enter the authentication flow to obtain a new token. The returned access tokens are usually valid for 24 hours.
TODO
For third-party authentication, we make use of Passport strategies.
Auth (Login Service
) interacts with other services as through a Node.js middleware library that downstream services can include in their routes. This would be added to the HTTP request filter chain and handle the authorization process to the service:
var auth = require('auth');
app.get("/api/random", auth.authorise(), RandomController.getRandom)
This auth
module behaves like an OAuth2 client, built on simple-oauth2.
The auth
module also keeps the shared secret or public key necessary for it to validate the JWT using node-jsonwebtoken.
URL | Description |
---|---|
POST /auth/basic | Given username & password, returns a JWT on successful authentication |
POST /auth/register | Given a payload of credentials, creates a new user resource |
POST /passwords/reset | Sends an password reset email |
POST /auth/facebook | Passport.js facebook authentication strategy |
POST /auth/google | Passport.js google oauth2 authentication strategy |
TODO: include a Postman Collection for testing
This section would document how to run the project locally.
Status Code | Meaning |
---|---|
200 OK | Generic successful execution. |
201 Created | Used as a response to POST method execution to indicate successful creation of a resource. |
400 Bad Request | Your request could not be understood by the server. This may be due to the data payload is not in the expected format. |
401 Unauthorized | The request requires authentication and none was provided. |
403 Forbidden | Request failed because you do not have authorization to access a specific resource. |
404 Not Found | The specified object could not be found. |
500 Internal Server Error | We had a problem with our server. Report the issue or try again later. |