Sunday, 13 August 2017

Authenticating With The Docker Hub V2 Api

This example is about authenticating with the docker hub v2 API and then getting the information/tags of the private repository.

Recently, i got this task and i was looking for any example. The public repository can be directly accessible using the v2 API, but for getting the private one, we must required authentication.

I have read their documentation and then tried the same using POSTMAN client first, once that is working, i have written a sample code.

First lets go with the postman client : 

There are two steps in it :

1. Getting the Auth Token by passing the username and password (POST)
2. Using that Auth token, query the docker hub v2 api (GET)


1. Getting the Auth Token : For getting the auth token we need to send a post request to https://hub.docker.com/v2/users/login/ with the username and password in the body. And in return it will return the auth token.


Post request to get the auth token.

2. Using that Auth token, query the docker hub v2 api : By using the above auth token, we can query the v2 api for getting the private repository tags info. We will require to pass the auth token in the headers.

Repository endpoint : https://hub.docker.com/v2/repositories/username/private-repo/tags



This will in-turn return the tags of the repository.

In node js :

1. Getting Auth token :

let dockerConfig = require('./config.js').dockerConfig,
    rp = require('request-promise'),
    _ = require('lodash'),
    R = require('ramda');


let getAuthToken = (username, password) => {

    let options = {
        method: 'POST',
        uri: `${dockerConfig.loginEndpoint}`,
        body: {
            "username": `${username}`,
            "password": `${password}`
        },
        json: true
    }
    return rp(options)

}

2. Getting the private repository tags using token :

let getImageTags = (username, repository, authtoken) => {
        let options = {
            method: 'GET',
            uri: `${dockerConfig.repositoryEndPoint}/${username}/${repository}/tags`,
            headers: {
                Authorization: `Bearer ${authtoken}`
            },
            json: true
        }
        return rp(options);
    }

Both the function will return promises, we can call them like this :

getAuthToken(config.username, config.password)
    .then((tokenInfo) => {
        console.log("token recieved");
        return getImageTags(config.username, config.repository, tokenInfo.token)
    })
    .then((tags) => {
        if (!_.isUndefined(tags) && !_.isNull(tags) && tags.count > 0) {
            let result = tags.results.map((tag) => (R.pick(["name"], tag)));
            console.log(result);
        }
        else
            console.log("No tags found");
    })
    .catch((err) => {
        console.error("Error Occured ", err.message);
    });


3. Config file, look like this : You will require to update it with your docker hub info.

module.exports = {
    dockerConfig : {
                loginEndpoint : "https://hub.docker.com/v2/users/login/",
                username :"username",
                password:"password",
                repository : "private_repo",
                repositoryEndPoint : "https://hub.docker.com/v2/repositories",
                tagsEndPoint : "tags"
        }

};

Here is the full working example, you can just clone it and start working.
https://github.com/UtkarshYeolekar/docker-auth-example

Hope it helps, Thanks!