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;
}
}