Technology
Published
11/24/2021

Most complicated auth flow I came across, feat: Cloudbeds

10 Minutes

SK Azharuddin
Published
11/24/2021
Technology

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere.

CLoudbeds auth integration with Node Js

Authentication flow could be multiple type, yes. However, recently I came across the most complicated one I even had.

Cloudbeds! I’ll explain what it is later in this blog, however, we needed to work with its API thus integrating authentication was the first thing on hand to get access and work with its protected routes.

What is Cloudbeds?

According to hospitalitynet (backlink: https://www.hospitalitynet.org/product/5000037.html), Cloudbeds' (backlink: https://www.cloudbeds.com) property management system (PMS) is a cloud-based front desk for your property. With it, you can check-in and check-out guests using an attractive drag-and-drop interface. Use it to push updated availability to your internet booking engine and channel manager.

In short, This is a PMS (backlink: What is Hotel PMS), to manage guest front in property like Hotel and Hostel.

The Challenge we got and flow we chose

Firstly, Cloudbeds’ auth flow is on OAuth 2.0 but we cannot have user’s (Client) login credential, instead Cloudbeds has Authorization Code flow (backlink: https://integrations.cloudbeds.com/hc/en-us/articles/360006450433-OAuth-2-0#1-initiate-oauth)

DiagramDescription automatically generated

As on the above image, Cloudbeds has two type of auth flow,

A:  Directly logging in by the user’s (Client) credential

B: Generating tokens by Authorization Code

Here, Cloudbeds says (backlink: https://integrations.cloudbeds.com/hc/en-us/articles/360006450433-OAuth-2-0),

“All OAuth 2.0 integrations must use the Authorization Code grant type when requesting access to customer data. At no point does the customer supply their Cloudbeds credentials to your application.”

So, we chose option B to go with.

DiagramDescription automatically generated

As we can see on the above image, there are three transactions,

  1. Firstly, we need to generate Authorization Code (option B)
  2. With the Auth Code we need to generate Access Token
  3. Boom, with the Access Token, get access to the protected route.

Now, here is something hidden I want to share with you.

Cloudbeds has two different tokens (backlink: https://integrations.cloudbeds.com/hc/en-us/articles/360006450433-OAuth-2-0#4-request-access-refresh-token-pair ):

access_token: Need to fetch Protected Route, has expiration.

refresh_token: Need to generate new access_token after its expiration.

Note: Easy right? Anha, too early to judge. Now let’s see what Cloudbeds says (backlink: https://integrations.cloudbeds.com/hc/en-us/articles/360006450433-OAuth-2-0#4-request-access-refresh-token-pair ) on these tokens,

Once you make a request to issue new access_token you can't use access_token you had before anymore. You must use the new one.

In case, you didn't save new access_token you still can use refresh_token to get it again but only until you start using new access_token.

Example:

  • You have the access_token0/refresh_token0 pair.
  • You make a request for a new access token by using refresh_token0 and our authorization server issues a new pair access_token1/refresh_token1.
  • Since this moment all your requests to get resource with access_token0 will fail.
  • But if you weren't able to save pair access_token1/refresh_token1 you can use refresh_token0 to acquire those tokens again.
  • As soon as you requested resource with access_token1 you can't use refresh_token0 anymore.

In Short, generate and use access_token only one at a time until its expiration and after expiration, generate a new pair of access_token and refresh_token with the last refresh_token and save the new refresh_token to generate new pair of access_token and refresh_token next time.

We will get more clarity on this while coding and implement section.

Ultimately, we need three method,

  1. Generate Authorization Code
  2. With Authorization Code generate a pair of access_token and refresh_token
  3. With refresh_token generate new pair of access_token and refresh_token

Here you might have a question on your mind just like I had, why can’t we generate pair of tokens with auth code every time?

I thought of this too and even tried, however, the auth code also has expiration like access_token and generating new auth code flow has multiple steps and requires client’s action every time (we will see this below). On the other side refresh_token gets generated along with the new access_token. I’m hoping we have clarity now, or you can go through the section again.

Now Let’s setup.

Client Action and Configuration

We are not asking the client for Cloudbeds login credentials, however, to access its data on Cloudbeds we need API credentials, now let’s see how the client can generate these for us and what are required.

Cloudbeds: Dashboard > Manage > Apps and Integration > API Credentials > New Credentials

The section we are looking for looks like this:

Graphical user interface, applicationDescription automatically generated

Name: Your App Name

Integration Type: Your industry

Redirect Uri: This is what requires from our side. Let’s go a bit deeper and understand what will happen on this endpoint.

On first step as discussed in the above section, we need Authorization Code to begin right! As per the flow (will reveal in the next section), we will redirect the client to the Cloudbeds auth approval page that looks something like this:

Graphical user interface, text, application, chat or text messageDescription automatically generated

After successful approval, Cloudbeds will send the the auth code to this Redirect Uri with parameter like: ?code={auth_code}

We will create the endpoint method on the coding section, for now we can just set this to /redirect. Ex: https://api-domain.com/api/redirect

Cloudbeds will send the auth code to this endpoint as:

https://api-domain.com/api/redirect?code=taas4acaefadr5g45s65vds

Now save, and it will look something like this:

Graphical user interfaceDescription automatically generated

Now, from here the credentials we need are CLIENT ID and CLIENT SECRET.

Statement: I know, you’re thinking we are still in the theory and not started coding yet, so, here is what I strongly believe, the best way to get something complicated like this done is getting the right knowledge aligned and segregated properly before jumping to the code. Believe or not this process helps me to resolve the problem more than 60% already and gives more clarity and understanding on what I’m actually doing, and I enjoy this more of course.

Now, let’s code.

The best part – Coding

Finally, we are done with brainstorm and have all the required knowledge with proper flow. In this stage we know what we must do.

Action refresher:

  1. Redirect Client to generate Authorization Code
  2. Generate tokens by Authorization Code
  3. Generate new pair of tokens by refresh_token
  4. Fetch protected API

On this project we chose Node Js for backend. Let’s setup a node project and start coding.

1. Setup Node App

If Node isn’t installed on you PC, please click here (backlink: https://nodejs.org/en/) and install it before moving forward.

Run the below command on your terminal to check if node has successfully installed.

Background pattern, rectangleDescription automatically generated

Create a folder where you want to set your project and open your terminal in that directory and run the below command.

This will create a node app. -y flag indicates to go with the default parameters. You can freely remove the flag to see what happens. However, better not on this project.

Now, let’s install all the dependencies at once, we need in the project.

Now, open package.json and replace the script with the below code:

TextDescription automatically generated

Now, add a folder named src in the root of the project and inside the folder create three files named, index.js, app.js and fetchApi.js. Afterall, the project structure should look something like this:

TextDescription automatically generated with medium confidence

Now, let’s add some code and run our server.

Open index.js file and add the below code, don’t worry, we aren’t going to copy-paste everything, I’ll explain every single code in the code comment or here.

TextDescription automatically generated

Here, we are creating a server with express and running on port 7000. Let’s create Hello route to check if everything is working fine.

Open app.js and add the below code:

TextDescription automatically generated

Here, we are creating a get route just to response Hello World.

Now, open terminal on your project’s directory and run the command below, finger crossed,

Shape, rectangleDescription automatically generated

If everything went well, you should see, server running on => 7000

Cool, now let’s create our first method.

2. Redirect To The Client Approval Page

As mentioned on Cloudbeds doc (backlink: https://integrations.cloudbeds.com/hc/en-us/articles/360006450433-OAuth-2-0#1-navigate-to-the-oauth-endpoint-to-authorize-the-test-property), to generate Authorization Code we need to redirect the user/client to:

“https://hotels.cloudbeds.com/api/v1.1/oauth?client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_CLIENT_URL&response_type=code”

however, both CLIENT_ID and REDIRECT_URL (where the auth code will be sent in query as explained above) we have already.

So, let just create an endpoint on this, open app.js and add the below code:

TextDescription automatically generated

Pretty self-explanatory. Now, Let’s create the redirect endpoint where we’ll receive the Authorization code.

3. Get Auth Code On Redirect Endpoint

On app.js add the below code:

TextDescription automatically generated

As discussed earlier, after successful approval from client side, we will be receiving auth code on the redirect endpoint in query. So here we receive it in req.query.code

Now, the second task was to generate tokens by auth code. Let’s do this.

4. Generate Tokens By Auth Code

Now, open fetchApi.js file and add the below code:

TextDescription automatically generated

Here, firstly we are importing the packages we need later in this code and declaring few variables.

CLOUDBEDS_URL: Cloudbeds base url, we need it multiple times on the below code

GRANT_TYPE: Grant types we need to send to the cloudbeds while generating tokens

DB: We had decided to not to use any database to keep it as simple as possible, so just to illustrate database action we are holding a CLIENT collection in the DB object.

Now, add the below code:

TextDescription automatically generated

Here, we are sending data in the body with post method through axios to the Cloudbeds endpoint to generate tokens.

Now, let’s create that data and use this method to get the tokens.

TextDescription automatically generated

Here, we are using form-data package to create "multipart/form-data" and generating tokens. Also saving the tokens to DB object to use it later in the code.

By the way, now we can generate the tokens, cheers.

Before moving to access the protected route, let’s handle the expiration, I mean let’s work on the third task and create a method to generate new pair of tokens with refresh_token.

5. Generate New Tokens By Refresh Token

In the fetchApi.js file add the below code:

TextDescription automatically generated

Here, generating new pair of tokens with refresh_token the same way we did before.

Now, let’s create a condition method which should be like, If the DB access_token hasn’t been expired, use it or if expired generate new pair of tokens with refresh_token and save it to the DB.CLIENT data.

TextDescription automatically generated

This is the method we will be using to get access_token, and this will handle the rest.

Now, final step, let’s test the flow and access the Cloudbeds protected route.

6. Fetch Protected Route

Okay, after all the hard work now we are about to get our rewards as green success message on the screen.

Let’s handle the api first in the fetchApi.js file as below:

TextDescription automatically generated

Here, we are fetching the access_token first, then fetching the loggedIn user data.

Let’s handle the api endpoint in app.js now as below:

TextDescription automatically generated

Voila, we have successfully integrated the Cloudbeds authentication with Node Js.

Conclusion

It was a bit longer interaction though worth learning and sharing the industry level knowledge and experience.

I know you also want to see the entire codebase like me, here is the Repo link (backlink: https://github.com/HeyAzhar/cloudbeds-auth-node) for you, cheere.

Wish you all the best. You are doing a great job.

References:

Cloudbeds OAuth Flow (backlink: https://integrations.cloudbeds.com/hc/en-us/articles/360006450433-OAuth-2-0)

Cloudbeds API (backlink: https://hotels.cloudbeds.com/api/docs/#api-Introduction-Welcome)

Thanks.

Subscribe To Our Newsletter

Join the Guest X-perience Community Of 500+  Hotels That Use Quoality Every Day

Start your free trail  & start growing today