Authentication in DADI API


  • DADI

    DADI API uses the client credentials flow of OAuth 2.0 to allow clients to access protected resources by obtaining an access token. First we'll setup an instance of API, then we'll go through creating some credentials, and using them to obtain a Bearer token, before we query a protected resource with our new token.

    API 2.X requires a MongoDB instance to work. If you don't have one of those setup already, you can easily start one with Docker to test with:

    $ docker run -d -p 27017:27017 mongo:3.2
    

    Let's create a new API app using the DADI CLI (npm install @dadi/cli -g):

    $ dadi api new simple-api
    ✔ Checking the available versions of DADI API
    ✔ Downloading boilerplate (100%)
    ✔ Installing DADI API (2.2.x)
    
    All done! Run the following command to launch your new instance of DADI API:
    
    cd simple-api && npm start
    

    Cool, now let's create some credentials:

    $ cd simple-api
    $ dadi api clients:add
    ? What is the client ID? testUser
    ? What is the secret? testPassword
    ? What type of access does the user require? user
    ✔ Created client with ID testUser and type user
    

    So now we have API setup, and a new user created, but where is this information stored? If you have a look in the config/config.development.json file, you'll find the auth block:

    "auth": {
      "tokenUrl": "/token",
      "tokenTtl": 1800,
      "clientCollection": "clientStore",
      "tokenCollection": "tokenStore",
      "database": {
        "hosts": [
          {
            "host": "127.0.0.1",
            "port": 27017
          }
        ],
        "username": "",
        "password": "",
        "database": "dadi-api"
      }
    }
    

    The tokenUrl defines where we query for a Bearer token. The tokenTtl is how long it will live for. The clientCollection is the Mongo collection which stores client credentials such as the one we created above, and the tokenCollection will store any Bearer tokens that we generate.

    The database block contains an array of hosts (allowing multiple in the case that you are using replica sets), a username, password, and finally, a database.

    Let's look in that database, assuming you have the mongo CLI tool installed:

    $ mongo dadi-api
    > show collections
    clientStore
    tokenStore
    

    Now query the clientStore collection to see if our user from earlier is in there:

    > db.clientStore.find()
    { "_id" : ObjectId("5a1403634e822a1250e45c56"), "clientId" : "testUser", "secret" : "testPassword", "type" : "user" }
    

    Perfect. Now let's start the API and generate some tokens.

    Cancel out of the mongo prompt with ctrl+c if you haven't already, then start API.

    $ npm start
    ...
    ----------------------------
    DADI API
    Started 'DADI API'
    ----------------------------
    Server:      127.0.0.1:3000
    Version:     2.2.5
    Node.JS:     8.9
    Environment: development
    ----------------------------
    

    Cool! Now let's try and access a resource without a token:

    $ curl http://127.0.0.1:3000/1.0/library/books
    
    {"statusCode":401}
    

    Now let's get a token. We'll need to send a POST request to /token with some JSON containing our clientId and our secret:

    curl \
      --request POST \
      --header "Accept: application/json" \
      --header "Content-Type: application/json" \
      --data "{\"clientId\":\"testUser\",\"secret\":\"testPassword\"}" \
      http://127.0.0.1:3000/token
    
    {"accessToken":"36afb59e-e26a-4a3b-bb03-c6226efdc4f0","tokenType":"Bearer","expiresIn":1800}
    

    We now have our Bearer token. We can use that to query the books collection again, but first, let's go back to mongo now and take a look in the tokenStore collection:

    $ mongo dadi-api
    
    > db.tokenStore.find()
    { "_id" : ObjectId("5a1405ac61977e126ced4fae"), "token" : "36afb59e-e26a-4a3b-bb03-c6226efdc4f0", "tokenExpire" : 1511263412358, "created" : ISODate("2017-11-21T10:53:32.358Z"), "value" : { "_id" : ObjectId("5a1403634e822a1250e45c56"), "clientId" : "testUser", "secret" : "testPassword", "type" : "user" } }
    

    As you can see, our token is sat in the tokenStore collection now.

    Now let's query the books collection, this time, with our Bearer token in the Authorization header:

    curl \
      --header "Accept: application/json" \
      --header "Content-Type: application/json" \
      --header "Authorization: Bearer 36afb59e-e26a-4a3b-bb03-c6226efdc4f0" \
      http://127.0.0.1:3000/1.0/library/books
      
    {"results":[],"metadata":{"limit":40,"page":1,"fields":{},"sort":{"name":1},"offset":0,"totalCount":0,"totalPages":0}}
    

    Bingo. We're in.

    You don't have to use cURL though, you can use anything that implements HTTP, so long as it follows the pattern above. If you use DADI Web, you don't even need to worry about the authorization flow as it's all built in.

    See our docs to more about Authentication in DADI API.


Log in to reply
 

Looks like your connection to DADI Forum was lost, please wait while we try to reconnect.