0

I have a hard time passing the right angular request to the header. This is my service:

import { Injectable } from '@angular/core';
import { HttpClient, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpHeaders } 
from '@angular/common/http';
import { Utente } from '../model/Utente ';
import { Prodotto } from '../model/Prodotto ';
import { OktaAuthService } from '@okta/okta-angular';
import { Observable, from } from 'rxjs';
import { Carrello } from '../model/Carrello ';
import { userInfo } from 'node:os';
import { getLocaleCurrencyCode } from '@angular/common';


const headers = new HttpHeaders().set('Accept', 'application/json');

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

 constructor(
private httpClient:HttpClient, private oktaAuth:OktaAuthService     ) {}

  getCarr(){
return this.httpClient.get<Carrello[]>('http://localhost:8080/prodotti/utente/vedicarrelloo', {headers} );
}
}

This is my spring method:

@Transactional(readOnly = true)
public List<Carrello> getCarrello(@AuthenticationPrincipal OidcUser utente){
    Utente u= utenteRepository.findByEmail(utente.getEmail());
    return carrelloRepository.findByUtente(u);
}

In console I get this error (error 500):

https://i.stack.imgur.com/BiONS.png

this error corresponds in my console to "java.lang.NullPointerException: null.

But if I access localhost: 8080, I can see the answer correctly, so I assume there is a problem in passing the request header in angular, can anyone tell me where am I wrong, please? I specify that I get this error only in the methods where the OidcUser is present, the rest works perfectly. Thank you!

Ramona
  • 21
  • 2

1 Answers1

0

You need to send an access token with your request. Like this:

import { Component, OnInit } from '@angular/core';
import { OktaAuthService } from '@okta/okta-angular';
import { HttpClient } from '@angular/common/http';

import sampleConfig from '../app.config';

interface Message {
  date: string;
  text: string;
}

@Component({
  selector: 'app-messages',
  templateUrl: './messages.component.html',
  styleUrls: ['./messages.component.css']
})
export class MessagesComponent implements OnInit {
  failed: Boolean;
  messages: Array<Message> [];

  constructor(public oktaAuth: OktaAuthService, private http: HttpClient) {
    this.messages = [];
  }

  async ngOnInit() {
    const accessToken = await this.oktaAuth.getAccessToken();
    this.http.get(sampleConfig.resourceServer.messagesUrl, {
      headers: {
        Authorization: 'Bearer ' + accessToken,
      }
    }).subscribe((data: any) => {
      let index = 1;
      const messages = data.messages.map((message) => {
        const date = new Date(message.date);
        const day = date.toLocaleDateString();
        const time = date.toLocaleTimeString();
        return {
          date: `${day} ${time}`,
          text: message.text,
          index: index++
        };
      });
      [].push.apply(this.messages, messages);
    }, (err) => {
      console.error(err);
      this.failed = true;
    });
  }
}

On the Spring side, if you want it to accept a JWT, you'll need to change to use Jwt instead of OidcUser. Example here.

@GetMapping("/")
public String index(@AuthenticationPrincipal Jwt jwt) {
    return String.format("Hello, %s!", jwt.getSubject());
}
Matt Raible
  • 8,187
  • 9
  • 61
  • 120
  • thank you very much for the reply. it is not clear to me, if that code must be inserted in the service or do I need to create a new component? in the latter case, how should I send the request then in the service to my method? thank you – Ramona Mar 18 '21 at 13:53
  • also, I specify that in my application, I have an auth.interceptor – Ramona Mar 18 '21 at 14:07