4

I am working on a NestJS API and am wanting to know about outgoing requests and certificates. We have a request we need to hit from within the API to allow it to run, but this API requires specific certificates. I have the certificates on my computer, but do not know how to pass them as an option. I also would like to avoid a new NPM package if possible, but that is not a requirement.

This is also done before the app is created, in the main.ts file, thus the following will not work as well:

const app = await NestFactory.create(ApplicationModule, {
    httpOptions: {
      ca: readFileSync('path/to/cert/file')
    }
  });

I have seen the following as a 'solution' for other languages:

ca: readFileSync('path/to/certificate')

However, this is not accepted anywhere in the HttpService for NestJS.

Here is an example of what I mean:

example.service.ts

import { HttpService, Injectable } from '@nestjs/common';
import * as fs from 'fs';

@Injectable()
export class ExampleService {
  constructor(private http: HttpService) { }

  async getRequest() {
    let response = null;

    const options = {
      headers: {
        'Content-Type': 'application/json'
      },
      ca: readFileSync('certs/cert.pem')
    };

    await this.http.get('http://apiurl.com/endpoint/path', options).subscribe(res => {
      response = res;
    };

    return response;
  }
}

The issue with HttpService currently is that it takes a 'configuration' as a second parameter, this parameter is a AxiosRequestConfig. This does not have any parameter ca, thus it won't recognize the above code, and unable to find documentation has made figuring this out more difficult.

I have also attempted to use the default http/https package that NodeJS uses and calling http.request(), but even the documentation there does not have anything on certificates.

I have thought about the possibility of intercepting the request, but could not find more information on that and how we could add the certs to the options.

I have also utilized export NODE_EXTRA_CA_CERTS=./certs/certificate.pem but am looking for a more specific solution that would allow specific requests to have certain certifications while others would not.

Is there a way to deal with this without installing another npm package?

Answer in case the duplicate doesn't help!

Since HttpService is built on top of http/https, it utilizes Axios for handling all requests. In order to add a certificate to a specific request, you need to create an agent, this is imported from https.

1: Create the agent such as:

const httpsAgent = https.Agent({ca: fs.readFileSync('path/to/cert/file'});

2.) Add the httpsAgent to the request options, there is a property in the object for this:

const reqOptions = {
httpsAgent: this.httpsAgent
};

3.) Add that to the request in the AxiosRequestConfig, it's the last parameter in any request:

this.http.get('http://apiurl.com/endpoint', reqOptions);

That is it! The finished product looks like this:

example.service.ts

import { HttpService, Injectable } from '@nestjs/common';
import * as fs from 'fs';

@Injectable()
export class ExampleService {
  httpsAgent = null;

  constructor(private http: HttpService) {
    this.httpsAgent = new https.Agent({ca: fs.readFileSync('path/to/cert/file')});
  }

  async getRequest() {
    let response = null;

    const options = {
      headers: {
        'Content-Type': 'application/json'
      },
      httpsAgent: this.httpsAgent;
    };

    await this.http.get('http://apiurl.com/endpoint/path', options).subscribe(res => {
      response = res;
    };

    return response;
  }
}
Sean
  • 155
  • 2
  • 7

0 Answers0