0

Im trying to consume a service in a Laravel (Backend) with Angular 2. I can doit without any problem if I doit with axios, but I need to doit with HttpClient

How can I translate this code:

const url = `${this.endPoint}/login`;
const urlCsrf = `${this.endPoint}/csrf-cookie`;
const body = { email, password };

axios.defaults.withCredentials = true;

axios.get(urlCsrf).then(() => {
    axios.post(url, body).then((resp) => {
        console.log(resp);
    });
});

to something like this but that it works:

//this code dont work returns csrf error
this.http.get(urlCsrf).subscribe(() => {
     this.http.post(url, body).subscribe((resp) => {
         console.log(resp);
    });
});
  • Have you tried using an interceptor https://stackoverflow.com/questions/35602866/how-to-send-cookie-in-request-header-for-all-the-requests-in-angular2 – Owen Kelvin May 02 '21 at 10:38
  • What about `this.http.get(urlCsrf, {withCredentials: true })` ? – David May 06 '21 at 08:11

2 Answers2

1

I have ran to the same issue recently here is what worked for me:

$data = 'client_id=xxxxxxxxx&client_secret=xxxxxxxxx&grant_type=client_credentials';
$url = "https://xxxxxxxxxxxxxxxxxxxxx.x/xx/xxxxx";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/x-www-form-urlencoded',
    'Content-Length: ' . strlen($data))
);
$contents = curl_exec($ch);
if (curl_errno($ch)) {
  echo curl_error($ch);
  echo "\n<br />";
  $contents = '';
} else {
  curl_close($ch);
}

if (!is_string($contents) || !strlen($contents)) {
echo "Failed to get contents.";
$contents = '';
}
$json = json_encode($contents);
Themodmin
  • 397
  • 2
  • 7
  • 18
1

That code translates to:

const body = {email, password}
this.http.get(urlCsrf).subscribe(() => {
     this.http.post(url, body, { withCredentials: true }).subscribe((resp) => {
         console.log(resp);
    });
});

If you want to write it in a more reactive way:

const body = {email, password}
this.http.get(urlCsrf).pipe(
     switchMap(()=> this.http.post(url, body, { withCredentials: true })
  ).subscribe((resp) => console.log(resp));

If you want to apply the withCredentials to all requests, you should take a look at the interceptors as mentioned in the comments. A quick example:

@Injectable()
export class CredentialsInterceptor implements HttpInterceptor {
  constructor() {}

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
      return next.handle(req.clone({ withCredentials: true }));
  }
}

and then import it in your AppModule

providers: [
  { provide: HTTP_INTERCEPTORS, useClass: EngagementXSRFInterceptor, multi: true },
]
eko
  • 37,528
  • 9
  • 64
  • 91