How to Implement OAuth in Express Gateway

How to Implement OAuth in Express Gateway

Express Gateway gives you the ability to spin up your own oauth provider from the command line. OAuth enables your users to delegate API endpoints to various apps via scopes. In this introductory article, you’ll learn how to get up and running with OAuth in Express Gateway.

Configuring the Gateway

The first step is to create a new gateway using the Express Gateway generator.

First, install the express-gateway npm module, and then create a new gateway using eg gateway create.

$ npm i -g express-gateway
$ eg gateway create
? What's the name of your Express Gateway? oauth
? Where would you like to install your Express Gateway? oauth
? What type of Express Gateway do you want to create? Getting Started with Express Gateway
   create package.json
   create server.js
   create config/gateway.config.yml
   create config/models/applications.js
   create config/models/credentials.js
   create config/models/users.js
   create config/system.config.yml

To start oauth, run the following commands:
    cd oauth && npm start
$

Second, edit the config/gateway.config.yml file and enable OAuth for the default pipeline as shown below. Once you turn on OAuth, you should see an ‘Unauthorized’ error when you visit http://localhost:3000/ip. You need to restart the server for config changes to take effect, so if you ran npm start be sure to kill the process and then re-run npm start.

http:
  port: 8080
admin:
  port: 9876
  hostname: localhost
apiEndpoints:
  api:
    host: localhost
    paths: '/ip'
serviceEndpoints:
  httpbin:
    url: 'https://httpbin.org'
policies:
  - basic-auth
  - cors
  - expression
  - key-auth
  - log
  - oauth2
  - proxy
  - rate-limit
pipelines:
  - name: default
    apiEndpoints:
      - api
    policies:
      # The below enables oauth for the localhost:8080/ip endpoint
      - oauth2:
      - proxy:
          - action:
              serviceEndpoint: httpbin
              changeOrigin: true

Next, you’ll need to create a new Express Gateway user. Users and applications have a one-to-many relationship, so you must create a user before you create an application. Make sure you do not restart the express gateway server after creating a user unless you have already set up a data store, because otherwise express gateway will use an in-memory data store and all your users will be deleted if the process is killed.

$ eg users create
? Enter username [required]: val
? Enter firstname [required]: Valeri
? Enter lastname [required]: Karpov
? Enter email: [email protected]
? Enter redirectUri: 
✔ Created c25fe037-30bb-42f7-9f3a-0264dcd60d14
{
  "firstname": "val",
  "lastname": "karpov",
  "email": "[email protected]",
  "isActive": true,
  "username": "val",
  "id": "c25fe037-30bb-42f7-9f3a-0264dcd60d14",
  "createdAt": "Wed Aug 16 2017 22:08:07 GMT-0700 (PDT)",
  "updatedAt": "Wed Aug 16 2017 22:08:07 GMT-0700 (PDT)"
}

Next, you need to create 2 credentials for this user: an OAuth credential and a basic-auth (password) credential. Express Gateway has a one-to-many relationship between users and credentials, so a user can have multiple credentials of different types (OAuth, key-auth, basic, etc.). The below creates an OAuth credential and a basic-auth credential with password “bacon”. Note that password doesn’t show up in the output of eg credentials create -t basic-auth, that’s for security.

$ eg credentials create -c val -t oauth2
✔ Created val
{
  "isActive": true,
  "createdAt": "Wed Aug 16 2017 22:08:13 GMT-0700 (PDT)",
  "updatedAt": "Wed Aug 16 2017 22:08:13 GMT-0700 (PDT)",
  "id": "val",
  "secret": "45e94fce-1524-4fbf-89b9-57a157079db7"
}
$ eg credentials create -c val -t basic-auth -p "password=bacon"
✔ Created val
{
  "isActive": true,
  "createdAt": "Wed Aug 16 2017 22:08:21 GMT-0700 (PDT)",
  "updatedAt": "Wed Aug 16 2017 22:08:21 GMT-0700 (PDT)",
  "id": "val"
}

Finally, you need to create an application, or “app”. The app represents a consumer of your API. Similar to how an app might use Facebook login and request access to the user’s photos, an Express Gateway app will log in against Express Gateway and receive permission to access a certain set of API endpoints. To create an app, you need to specify an associated user, a name, and a redirect URI, which is the URL the user will be directed to after successfully logging in.

$ eg apps create -u val
? Enter name [required]: testapp
? Enter redirectUri: http://google.com
✔ Created 84828eee-2832-4ecd-8155-008fbea0f485
{
  "name": "testapp",
  "redirectUri": "http://localhost:8080/ip",
  "isActive": true,
  "id": "84828eee-2832-4ecd-8155-008fbea0f485",
  "userId": "val",
  "createdAt": "Wed Aug 16 2017 22:08:38 GMT-0700 (PDT)",
  "updatedAt": "Wed Aug 16 2017 22:08:38 GMT-0700 (PDT)"
}

Walking Through the Oauth Flow

Now that you’ve set up the necessary objects, let’s walk through the actual oauth flow using Chrome and cURL. You’ll notice that if you visit http://localhost:8080/ip in Chrome you’ll get an ‘Unauthorized’ error message as shown below.

Your gateway.config.yml file protects the /ip endpoint behind oauth middleware, so you need to get an access token by walking through the Express Gateway oauth flow. To start, you need to visit the /oauth2/authorize endpoint and specify the following parameters in the URL query string:

  • response_type: String containing either ‘bearer’ or ‘token’. For this example you’ll use ‘token’.
  • client_id: String containing the id of your app from the output of eg apps create -u val. In this case, ‘84828eee-2832-4ecd-8155-008fbea0f485’, but it will be different for you.
  • redirect_uri: String that must match the redirectUri you specified when running the eg apps create -u val command.

Here’s how the full URL looks:

http://localhost:8080/oauth2/authorize?response_type=token&client_id=803b1da9-879d-44b5-8d77-5199c4e11fba&redirect_uri=http://localhost:8080/ip

When you visit this URL, you should get redirected to a login screen. You can configure the UI, but for this article you’ll just use Express Gateway’s minimal built-in login screen.

Enter in the username and password you entered when you ran eg users create. If you’re following this article exactly, the username will be “val” and the password will be “bacon”. You will then get redirected to a page that asks you to authorize your app ‘testapp’ to access your account. In more advanced applications, this is also where Express Gateway will ask for other permissions (scopes).

Hit the ‘Allow’ button to continue the flow and you’ll get an ‘Unauthorized’ error.

Don’t panic, you didn’t do anything wrong, this is actually the right behavior.

OAuth is all about granting API access to client apps, and does so by putting the access_token in the URL. This is the access token you use in the Authorization header in your HTTP requests to authenticate to the oauth policy. Your app will have to do that on its own, but, in the interest of keeping this example lean, you’ll just use curl.

Copy the access_token from the URL bar. The access_token is URI-encoded, so first decode it using Node.js’s shell.

$ node
> decodeURIComponent('599f481560a74545a0f9d54a2e3f7dde%7Cb1f7252fe6f24a0d98d98cc87693579c')
'599f481560a74545a0f9d54a2e3f7dde|b1f7252fe6f24a0d98d98cc87693579c'
>

Next, use curl to make an HTTP request with the token in the Authorization header as shown below:

$ curl -H "Authorization: Bearer 599f481560a74545a0f9d54a2e3f7dde|b1f7252fe6f24a0d98d98cc87693579c" http://localhost:8080/ip
{
  "origin": "76.220.52.187"
}
$

Congratulations, you’ve successfully generated an access token through Express Gateway’s oauth flow and used it to make an authenticated request!

Moving On

This article is just a “Hello, World” level example for OAuth with Express Gateway. In this example you used Express Gateway as both the auth server (the server requesting auth) and the resource server (the server granting access to the API).

However, Express Gateway can also serve as an auth server for an external API, so you can add OAuth permissions on top of any API. I’d recommend you try actually building a client-side app that uses Express Gateway OAuth for login, and read up on scopes so you can control which portions of your API your app has access to.


  • Sign up for our private beta – your feedback helps prioritize our roadmap with the most value realized within the shortest amount of time
  • Check out our Open Source Initiative: The Express Gateway
  • Learn about the inaugural feature set we’re striving for to make APIs repeatedly fast, easy and manageable as you evolve through the API lifecycle itself.
  • Sign up for the latest development on APIs and microservices.