3
votes

i am trying to call an api where i got stuck with the CORS error.

when i tried with "https://...." , i hit the following error with service being failed.

status Code: 422.

OPTIONS https://xyz/login?username=xxx&password=xxx 422 (Unprocessable Entity) Access to XMLHttpRequest at 'https://xyz/login?username=xxx&password=xxx' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

when i tried with "http://...." i get the following error.

status Code: 307 Temporary Redirect

Access to XMLHttpRequest at 'http://xyz/login?username=xxx&password=xxx' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.

I tried adding headers but the added headers won't show on the browser.

Request headers look like below:

Provisional headers are shown Access-Control-Request-Headers: content-type Access-Control-Request-Method: POST Origin: http://localhost:4200 Referer: http://localhost:4200/login User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36

Please help me resolve the issue,

my component.ts looks like this

import { FormControl, FormGroup, FormGroupDirective, NgForm, Validators, FormBuilder } from '@angular/forms';
import { ErrorStateMatcher } from '@angular/material/core';
import { Router, ActivatedRoute } from '@angular/router';
import { first } from 'rxjs/operators';

import { AuthenticationService } from '../services';


@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit{
  loginForm: FormGroup;
   returnUrl: string;
   error = '';

  constructor(
    private formBuilder: FormBuilder,
    private route: ActivatedRoute,
    private router: Router,
    private authenticationService: AuthenticationService) {}

    ngOnInit() {
       this.loginForm = this.formBuilder.group({
           username: ['', [Validators.required , Validators.email]],
           password: ['', [Validators.required]]
       });

       // get return url from route parameters or default to '/'
       this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
   }

   get f() { return this.loginForm.controls; }

    onSubmit() {
        this.authenticationService.login(this.f.username.value, 
            this.f.password.value)
            .pipe(first())
            .subscribe(
                data => {
                    this.router.navigate([this.returnUrl]);
                },
                error => {
                    this.error = error;
                });
    }

}```

and my authentication.service.ts looks like this 

``import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { map } from 'rxjs/operators';
import { Http, Headers, RequestOptions, Response, ResponseContentType } from '@angular/http';

@Injectable({ providedIn: 'root' })
export class AuthenticationService {

    constructor(private http: HttpClient) { }

    login(username: string, password: string) {
      const httpOptions = {
       headers: new HttpHeaders({
                    'Content-Type': 'application/json',
                    'Access-Control-Allow-Origin': '*',
                    'Access-Control-Allow-Credentials': 'true'
       })
     };
        return this.http.post(`https://xyz/login 
                         username=xxx&password=xxx, httpOptions)
            .pipe(map(user => {
                if (user) {
                    // some logic
                }
                return user;
            }));
    }
}```

i want to resolve the CORS issue and make successful api call either from client side or from server side. Being fairly new to angular, any details/step by step instructions are appreciated.

Also , i would want to know why added headers wont show on browser. Am i missing anything
3
This issue is because of backend CORS configuration, add CORS allow '*' in backend codeRaghul Selvam

3 Answers

5
votes

CORS issues are common when developing from localhost. You have some options to fix this:

1) If you have control of your server, add this header to the response:

Access-Control-Allow-Origin: *

2) If you do not own the server with the endpoint, install this chrome extension. This will add the header and allow localhost requests.

3) If you dont use chrome or if you want to use a proxy in your code, use this proxy. Your urls will end up something like this:

https://crossorigin.me/http://xyz/login?username=xxx&password=xxx
1
votes

Maybe a little bit too late with this answer, but.. 1st issue: If back-end app doesn't return Access-Control-Allow-Origin then you can add it to security configuration:

protected void configure(HttpSecurity http) throws Exception {
http.headers()
            .addHeaderWriter(
                    new StaticHeadersWriter("Access-Control-Allow-Origin", "address for your front-end here")
            );
}
0
votes

i've used fetch api with cors-anywhere proxy to resolve the issue.

onSubmit({ value, valid }: { value: IUserLogin, valid: boolean }) {
  let result;
  const params = {
    "username": value.username,
    "password": value.password
  }

  let url = `https://company.com/login?username=${params.username}&password=${params.password}`;
  const proxyurl = "https://cors-anywhere.herokuapp.com/";
  let req = new Request(proxyurl + url, {
    method: 'POST',
    headers: {

      'Authentication': `Basic ${value.username}:${value.password}`,
      'Content-Type': 'application/json',
      'mode': 'no-cors'

    }
  });

  fetch(req)
    .then(response => response.text())
    .then((contents) => {
      result = JSON.parse(contents);
      console.log(JSON.parse(contents).data)
      if (result.data) {
       // do something
      } else {
       // do something
      }
    })
    .catch(() => console.log("Can’t access " + url + " response. Blocked by browser?"))


}