Skip to main content

Ask for a username and password

Some clients can send a username and password but cannot sign tokens, an internal tool for example, or a person who opens the API in a browser. HTTP basic authentication carries both in the Authorization header of every request. The plugin basic-auth on the route checks them against the credentials of your consumers. This guide puts basic-auth on orders-api and gives the consumer mobile-app a username and password. At the end, a request with the username and password of mobile-app reaches your backend without the password, and a request without them, or with a wrong password, is answered 401.

Before you start​

  • This guide starts from orders-api as Route requests to a backend leaves it, with no other plugin. A plugin from another guide that this page does not name can change the answers below; remove it first or work on a copy of the route.
  • One authentication plugin per route. With key-auth from Require an API key or jwt-auth from Accept signed tokens still on orders-api, a request also needs a key or a token, and a username and password alone are answered 401. Do this guide on a copy of orders-api, or remove both from it first.
  • To remove a plugin, open the actions menu at the right of its row on the route's Plugins tab and select Remove. Put key-auth back when you return to the other guides, which start from orders-api with key-auth.
  • The host name of your gateway. In the console it is the first part of the Address line on a route's Overview tab, api.example.com in this page's examples; replace it in every request below.
  • The requests below call /orders/42.
  • HTTPS in front of the route, since every request it admits carries a password. Serve HTTPS with your certificate shows how.
  • On a route that already serves clients, do the steps in a different order. Create the consumer and its credential first, steps 4 and 5, and add basic-auth to the route last, since from then on every request without a known username and password is refused.
  • The Editor or Environment administrator role in this environment. Only a role that manages consumers and credentials can create them and see a password.

Steps​

1. Open the route's Plugins tab​

Open orders-api under Routes, select its Plugins tab, then Add plugin at the top right of the tab.

2. Choose basic-auth​

Open the Authentication category, or type basic-auth in the search box. Select basic-auth, then Configure. A panel with the plugin's form opens.

3. Name the realm, hide the password and add the plugin​

Fill in these fields and leave Anonymous consumer empty.

FieldValueWhy
RealmOrders APIThe name the client's sign-in prompt shows, sent in WWW-Authenticate on every 401. No double quotes or backslashes.
Hide credentialsonThe Authorization header that carried the username and password is removed before the request goes on, so your backend never sees the password.

Select Add plugin at the bottom of the panel. The tab now lists basic-auth, and the plugin is saved like this:

The Add basic-auth panel with the realm the browser shows filled in.
basic-auth · as the console saves it
{
"realm": "Orders API",
"hide_credentials": true
}

From now on, a request to orders-api without a known username and password is answered 401. The next steps give mobile-app its username and password.

4. Create the consumer​

If mobile-app exists already, go on with step 5. Otherwise create it as step 4 of Require an API key shows, with the username mobile-app.

5. Give the consumer its username and password​

Create a credential on mobile-app as steps 1 to 3 of Give a client its key, and replace it show, with these values. Leave the other fields as they are.

FieldValueWhy
Credential IDmobile-app-passwordA name for this credential. The ID cannot be changed later.
Pluginbasic-authThe plugin this credential is for.
Usernamemobile-appThe name the client signs in with.
Passwordthe passwordThe password the client sends together with this username. Treat it like any password: long and random, from a password generator.

The form warns beside Password: Avoid spaces and colons: the client's whitespace is stripped and its password is read up to the next colon, so such a credential never signs in.

Select Create credential. The credential is saved like this:

basic-auth credential · as the console saves it
{
"username": "mobile-app",
"password": "<secret>"
}

6. Hand the password over​

Give the username and password to the team that runs the client the way you pass other secrets, never by mail or chat.

Check it​

Send a request with the username and password of mobile-app. Then send one without a username and password, and one with a wrong password.

curl
curl -i -L 'https://<gateway host>/orders/42' \
-u 'mobile-app:<the password of mobile-app>'
Without a username and password
A request without credentials is answered 401 and asks for them with WWW-Authenticate: Basic realm="Orders API", so a browser opens its sign-in prompt with that name.
With the right password
A request with the username and password of mobile-app is answered 200; the credentials are removed before the request reaches the backend, which receives X-Consumer-Username: mobile-app instead.
With a wrong password
A request with the right username and a wrong password is answered 401 with Invalid user authorization.

In a browser, the first answer opens a sign-in prompt that shows the realm, Orders API.

What to know​

  • Your backend receives the consumer's username in X-Consumer-Username, so it tells clients apart without seeing the password.
  • A realm with a double quote or a backslash in it is refused when you save, and so is one longer than 128 characters.
  • One plugin per credential. A consumer that also signs in with an API key holds a key-auth credential beside this one.
  • Every consumer with a known username and password passes. To let only some of them in, add Allow only named clients on the same route.
G8 dev