Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proxy configuration is not working in angular 6

I have metronic_v5.5.2 Angular Version and I am trying to integrate Its angular version with my backend API.

As I am pretty new to all this, Now the issue is with my proxy configuration that is not working according to my expectations.

The following is the code of proxyconfig.json file

{
    "/api": {
        "target": "https://localhost:5001",
        "secure": false,
        "changeOrigin": true,
        "logLevel": "debug"
    }
}

Image is showing that the request is routing to the URL "https://localhost:5001/api/auth/login" POST /api/auth/login -> https://localhost:5001

But In browsers' console this request is actually routing to the URL http://localhost:4200/api/auth/login which return 401 error. I am unable to route on clicking of button to the url: https://localhost:5001/api/auth/login

Following is the HTML Code

<!--begin::Form-->
<form class="m-login__form m-form" name="form" (ngSubmit)="f.form.valid && submit()" #f="ngForm" novalidate>
    <div class="form-group">
        <mat-form-field>
            <mat-label>Email</mat-label>
            <input matInput type="email" name="email" placeholder="Email address" autocomplete="off" [(ngModel)]="model.email" #email="ngModel" email="true" required>
        </mat-form-field>
    </div>
    <div class="form-group">
        <mat-form-field>
            <mat-label>Password</mat-label>
            <input matInput minlength="4" type="password" name="password" placeholder="Password" autocomplete="off" [(ngModel)]="model.password" #password="ngModel" required>
        </mat-form-field>
    </div>
</form>
<!--end::Form-->

<!--begin::Action-->
<div class="m-login__action m-login__action--fit">
    <a href="javascript:;" (click)="forgotPasswordPage($event)" class="m-link">
        <span translate="AUTH.GENERAL.FORGOT_BUTTON">Forgot Password?</span>
    </a>
    <m-spinner-button [options]="spinner" (click)="submit()">{{'AUTH.LOGIN.BUTTON' | translate}}</m-spinner-button>
</div>

Following is the login.component.ts code

submit() {
        this.spinner.active = true;
        if (this.validate(this.f)) {
            this.authServiceDb.logindb(this.model).subscribe(response => {
                    this.router.navigate(['/']);
                    this.alertify.success('Logged In Successfully');
                    this.spinner.active = false;
                    this.cdr.detectChanges();
            }, error => {
                this.alertify.error(error);
            });
        }
    }

function the code for authdb exported class is given blow, Edit

import { Injectable } from '@angular/core';
import { Http, Headers, RequestOptions, Response } from '../../../node_modules/@angular/http';
import { map, catchError } from 'rxjs/operators';
import { throwError } from '../../../node_modules/rxjs';
import { tokenNotExpired, JwtHelper } from 'angular2-jwt';

@Injectable({
    providedIn: 'root'
})
export class AuthdbService {
    baseUrl = 'api/auth/';
    userToken: any;
    decodedTokenn: any;
    jwtHelper: JwtHelper = new JwtHelper();
    constructor(private http: Http) { }
public logindb(model: any) {
    return this.http.post(this.baseUrl + 'login', model, this.requestOptions()).pipe(map((response: Response) => {
      const user = response.json();
      if (user) {
        localStorage.setItem('token', user.tokenString);
        this.decodedTokenn = this.jwtHelper.decodeToken(user.tokenString);
        this.userToken = user.tokenString;
      }
    })).pipe(catchError(this.handleError));
  }
  register(model: any) {
    return this.http.post(this.baseUrl + 'register', model, this.requestOptions()).pipe(catchError(this.handleError));
  }
  loggedIn() {
    return tokenNotExpired('token');
  }
  private requestOptions() {
    const headers = new Headers({
      'Content-type': 'application/json'});
    return new RequestOptions({headers: headers});
  }
  private handleError(error: any) {
    const applicationError = error.headers.get('Application-Error');
    if (applicationError) {
      return throwError(applicationError);
    }
    const serverError = error.json();
    let modelStateErrors = '';
    if (serverError) {
      for (const key in serverError) {
        if (serverError[key]) {
          modelStateErrors += serverError[key] + '\n';
        }
      }
    }
    return throwError(
      modelStateErrors || 'Server Eroor'
    );
  }
}

And In My package.json I have the following code

{
    "name": "default",
    "version": "0.0.0",
    "license": "MIT",
    "scripts": {
        "ng": "ng",
        "start": "ng serve --proxy-config proxyconfig.json",
        "build": "ng build --prod",
        "test": "ng test",
        "lint": "ng lint",
        "e2e": "ng e2e"
    },
    "private": true,
    "dependencies": {
        "@angular/animations": "^6.1.0",
        "@angular/cdk": "^6.4.0",
        "@angular/common": "^6.1.0",
        "@angular/compiler": "^6.1.0",
        "@angular/forms": "^6.1.0",
        "@angular/http": "^6.1.0",
        "@angular/platform-browser": "^6.1.0",
        "@angular/platform-browser-dynamic": "^6.1.0",
        "@angular/platform-server": "^6.1.0",
        "@angular/router": "^6.1.0",
        "@kolkov/angular-editor": "^0.10.3",
        "@ng-bootstrap/ng-bootstrap": "^2.2.0",
        "@ngx-loading-bar/core": "^2.1.1",
        "@ngx-translate/core": "^10.0.2",
        "@types/lodash": "^4.14.112",
        "alertifyjs": "^1.11.1",
        "angular-in-memory-web-api": "^0.6.0",
        "angular2-jwt": "^0.2.3",
        "chart.js": "^2.7.2",
        "classlist.js": "^1.1.20150312",
        "core-js": "^2.5.7",
        "hammerjs": "^2.0.8",
        "lodash": "^4.17.10",
        "material-design-icons": "^3.0.1",
        "ng2-charts": "^1.6.0",
        "ngx-auth": "4.0.0",
        "ngx-highlightjs": "^2.0.4",
        "ngx-perfect-scrollbar": "^6.2.0",
        "ngx-permissions": "^5.0.0",
        "object-path": "^0.11.4",
        "rxjs-compat": "^6.2.2",
        "rxjs-tslint": "^0.1.5",
        "web-animations-js": "^2.3.1",
        "zone.js": "^0.8.26"
    },
    "devDependencies": {
        "@angular-devkit/build-angular": "^0.7.0",
        "@angular/cli": "^6.0.8",
        "@angular/compiler-cli": "^6.1.0",
        "@angular/core": "^6.1.0",
        "@angular/language-service": "^6.1.0",
        "@angular/material": "^6.4.0",
        "@angular/material-moment-adapter": "^6.4.0",
        "@types/jasmine": "^2.8.8",
        "@types/jasminewd2": "^2.0.3",
        "@types/node": "^10.5.2",
        "codelyzer": "^4.4.2",
        "jasmine": "^3.1.0",
        "jasmine-core": "^3.1.0",
        "jasmine-spec-reporter": "~4.2.1",
        "karma": "~2.0.4",
        "karma-chrome-launcher": "^2.2.0",
        "karma-coverage-istanbul-reporter": "^2.0.1",
        "karma-jasmine": "^1.1.2",
        "karma-jasmine-html-reporter": "^1.2.0",
        "moment": "^2.22.2",
        "protractor": "^5.3.2",
        "rxjs": "^6.2.2",
        "ts-node": "^6.0.3",
        "tslint": "~5.9.1",
        "typescript": "2.7.2"
    }
}
like image 714
Hafiz Siddiq Avatar asked Aug 28 '18 11:08

Hafiz Siddiq


3 Answers

It took me a couple of hours to fix incorrect routing of POST /api/auth/login to https://localhost:5001 which is in the image you provided.

Following config fixes the routing of POST /api/auth/login to https://localhost:5001/api/auth/login.

{
    "/api": {
        "target": "https://localhost:5001/api",
        "changeOrigin": true,
        "logLevel": "debug",
        "pathRewrite": { "^/api" : "" }
    }
}
like image 167
Mandakh Avatar answered Nov 03 '22 00:11

Mandakh


You said you are new to this, so let me explain something simple first.

When you call http.post the first parameter is the url that will be contacted. So:

this.http.post(this.baseUrl + 'login', ...

will become

this.http.post('api/auth/login', ...

because you set baseUrl and added 'login':

baseUrl = 'api/auth/';

But your code does not say which protocol to use (http or https) NOR which domain:port to call (eg. http://mydomain:port/api/auth/login).

Therefore Angular will default to 'http' and to the domain and port that IT is using, which is localhost:4200. So your request then becomes:

http://localhost:4200/api/auth/login

That is why you see that in the console. Angular is completely ignoring your proxy file. I think the reason is either the name, or location (it should normally be in your project's root folder) or you have not told Angular to load it.

You need to tell Angular to actually use it when it starts up. So in package.json you need something like this:

"start": "ng serve --proxy-config proxyconfig.json"

This tells Angular-CLI that when you use the npm run start (or just npm start) command to start the app, it should load the proxy data from that json file in the root folder.

I would advise reading this tutorial also.

Also, I think you have /* missing from your proxyconfig:

{
    "/api/*": {
        "target": "http://localhost:5001",
        "secure": false,
        "changeOrigin": true,
        "logLevel": "debug"
    }
}
like image 40
rmcsharry Avatar answered Nov 02 '22 23:11

rmcsharry


I had this same issue and adding proxyConfig option to the serve target did the job.

Go to angular.json -> within serve add the key:value pair "proxyConfig": "proxy.conf.json"

like this -

"architect": {
  "serve": {
    "builder": "@angular-devkit/build-angular:dev-server",
    "options": {
      "browserTarget": "your-application-name:build",
      "proxyConfig": "proxy.conf.json"
    },

btw, I got this from here

like image 45
N K Avatar answered Nov 02 '22 22:11

N K