Skip to main content

How to secure API token when deploying Angular application with Netlify

As you get more into front-end development, you realize that visual looks and GUI are not the most important thing. Yes, they are the most important thing for the user because it's what they first see. However, there are other equally, if not more important, application segments that a developer needs to take care of. One of them is security. This is such an important aspect that, if you don't have it covered, you can't even deploy your application and have your clients use it safely.

 

Consider the use of  APIs. Almost all front-end applications use APIs today. For young developers, it's encouraging to learn API implementation, because it's something they will surely use in their career. There are numerous APIs online to use freely, mostly for the purpose of learning and showcasing your work. Some of them can be found here Free API.

In my previous post Using GitHub REST API to display your repositories with Angular, I wrote about GitHub API and how to fetch and display GitHub repositories. This post covers the security and discusses how to protect your GitHub API key so that it is not visible in browser's Network tab. There are several ways this can be achieved. I have used package dotenv which has the power to access the API key at the runtime, so that you don't have to save the it anywhere in your application. However, you do need to use some kind of back-end service from where you will access the key. This is where serverless functions come into play.

What are serverless functions good for?

Serverless functions not only make the deployment of new code quicker, simpler, and easy to automate — they also significantly decrease the possibility of downtime during a deploy. In short, serverless functions improve the performance of your application and the experience of your developers and customers.


You can use AWS Netlify which is a serverless platform for front-end developers to use for building and deploying web apps. Here are the steps for integrating Netlify with Angular in local development:

  • Add these properties to tsconfig.json:

     "esModuleInterop": true,

    "isolatedModules": false,

  • Create account on Netlify (Starter plan is free) 

  • Install netlify-cli and dotenv packages

  • Add netlify script command to package.json

        "netlify""netlify"

  • Create toml file with configuration which tells where the function is and where the published website is (if you don't have the build setup in package json, just put src)

  • Run netlify development server with command

     netlify dev or npm run netlify dev

Netlify handles passing the event object, consequently you will see your application deployed locally.

 

The question you are probably asking yourself is where to place the API key and where from in the application to access it? After some time of researching this problem, I realize the solution is quite simple:

  1. Create an empty folder at the root and name it functions
  2.  Add a script to functions folder (fetch-git.ts)
  3.  Create .env file at the root of your project and add API key there

The script will communicate with GitHub API through the API access URL to which you will pass your API token placed in the .env file at the root of the project. Both .env and netlify should be added to gitignore.

 

const API_SECRET = process.env.API_SECRET;

const url =`https://api.github.com/users/username/repos?access_key=${API_SECRET}`;


I used axios in my script to talk to the API, so be sure to install it if you want to follow along.
Here is how my fetch-git.ts script looks like:

 

import Handler } from '@netlify/functions';

import axios from 'axios';

require('dotenv').config();

export const handlerHandler = async (eventcontext=> {

    const API_SECRET = process.env.API_SECRET;

    const url = `https://api.github.com/users/username/repos?access_key=${API_SECRET}`;

    try {

        const { data } = await axios.get(url);

        return {

            statusCode: 200,

            body: JSON.stringify(data),

        };

    catch (error{

        const { statusstatusTextheadersdata } = error.response;

        return {

            statusCode: status,

            body: JSON.stringify({ statusstatusTextheadersdata }),

        };

    }

};

 

Since we are talking about Angular, our component logic is placed in the src folder, which is outside of the netlify functions folder. We want to make a call to this script from our component or a service, but it has to go through netlify functions, so that our API key is not exposed. All you need to do in your service is to make a call to netlify function fetch-git. URL looks like this:
 
'.netlify/functions/fetch-git'
 

Angular service:

 

import { Injectable } from '@angular/core';

import axios from 'axios';

@Injectable({

    providedIn: 'root',

})

export class WorkService {

    constructor() {}

    handler = async () => {

        const url = '.netlify/functions/fetch-git';

        try {

            const { data } = await axios.get(url);

            return data;

        catch (error) {

            const { statusstatusTextheadersdata } = error.response;

            return {

                statusCode: status,

                body: JSON.stringify({ statusstatusTextheadersdata }),

            };

        }

    };

}


And then, as it usually goes, inject the service in your component and display the returned data from the API. 

      displayRepoList() {

        this.workService.handler().then(

            (res=> {

                this.repositories = res;

            },

            (err=> {

                console.log('failed'err);

            }

        );

    }


Make sure that your API key is placed only in the .env file at the root of your project, and nowhere else. In your fetch-git script, you access the API key through process.env which is possible because you installed dotenv package. The Netlify function fetch-git has access to the API key during the runtime. Your API key should not be visible anywhere in the developer tools. Check the Network tab and fetch-git request to make sure of that.

Happy Coding :)

Comments