Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular, Node API, How to SSL Localhost, DEPTH_ZERO_SELF_SIGNED_CERT, Cookie

LocalHost, Angular 11 (https://localhost:4200) and Node API (https://localhost:3001), both are using OpenSSL, browser is Chrome. To iron out Status: CORS error (due to diff ports) I follow this adding Proxy, got this in Angular's console

[HPM] Error occurred while trying to proxy request /somewhere1 from localhost:4200 to https://localhost:3001 (DEPTH_ZERO_SELF_SIGNED_CERT) (https://nodejs.org/api/errors.html#errors_common_system_errors)

Following didn't help:

  1. Confirmed the Chrome brought up by F5 has chrome://flags/#allow-insecure-localhost Enabled.
  2. Added process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; to Node API's server.js.

Proxy.conf.json

{
    "context": 
    [
        "/path1",      
        "/path2"
    ],
    "target" : "https://localhost:3001", 
    "secure": true,    
    "changeOrigin": true,  
    "rejectUnauthorzied": false,
    "logLevel": "info"  
}

angular.json

"serve": {
          ...
          "options": {
            "browserTarget": "myapp:build",
            "ssl": true,
            "proxyConfig": "src/proxy.conf.json"

Call API:

private http: HttpClient;
const httpOptions = 
      {
          headers: new HttpHeaders({'Content-Type': 'application/json'}),
          rejectUnauthorized: false
      };
this.http.post<any[]>("/somewhere1/hello", {}, httpOptions).subscribe

Believe this is Angular end.

like image 451
Jeb50 Avatar asked Dec 04 '25 13:12

Jeb50


1 Answers

After days of frustration, I'm finally able to resolve them all and posting the solution here hope will help someone forward.

Environment:

  1. Angular 11/12 front-end uses 3rd-party authentication such as Google.
  2. API server is node 14.
  3. Both are httpS/SSL.

Solution:

  1. Follow this article to create trusted .crt and .key files
  2. I didn't add localhost to hosts file.
  3. Add a proxy.conf.js (or .json file with conformed format) and include it into angular.json file.
  4. No need to specify httpOption for each individual http call.
  5. API node, add the two files from 1 to server.js.

My Proxy.conf.js:

const PROXY_CONFIG = 
[
    {
        context: 
        [
            "/path1",      
            "/path2",
            ...
        ],
        "target" : "https://localhost:3001", // I use 3000 for non-SSL
        "changeOrigin": true,  // helps on CORS Error in F12
        "logLevel": "debug",
        "rejectUnauthorzied": true, // or false if ok for you
        "secure": false,            // PROD must be "true", but DEV false else "UNABLE_TO_VERIFY_LEAF_SIGNATURE"
        "strictSSL": true,          // false is default
        "withCredentials": true     // required for Angular to send in cookie
    }
]
module.exports = PROXY_CONFIG;

My Angular.json:

"architect": {
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "myapp:build",
            "ssl": true,
            "proxyConfig": "src/proxy.conf.js"
            ...

My Server.js:

const fs = require("fs");
// following are the two files mentioned in No.5
const HttpSOptions = 
    {
        key: fs.readFileSync('ssl\\server.key'),
        cert: fs.readFileSync('ssl\\server.crt')
    }
const httpSServer = httpS.createServer(HttpSOptions, app);
httpSServer.listen(3001, ()=>{console.log('httpS is on 3001');});

To verify certificates are FULLY trusted by Chrome, open one of your API URL call in Chrome, for example http://localhost:3001/path1/func/xyz, you should not see this

enter image description here

like image 117
Jeb50 Avatar answered Dec 07 '25 11:12

Jeb50