Autoryzacja OAuth w Angular

0

Cześć,

tworze SPA, które opieram się o RESTowe API. Atuoryzacja w tym api odbywa się przez Bearer token.
A więc napisałem sobie interseptor, który dodaje odpowiedni nagłówek.

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if(!(req.headers.get("Content-Type") === "application/x-www-form-urlencoded")) {

      const authReq = req.clone({
        headers: req.headers.set('Authorazation', 'Bearer ' + this.callToken()
          .then(resp => resp)
          .catch(err => console.log(err)))
      });
      return next.handle(authReq)
    }else {
      return next.handle(req);
    }
  }

i te część działa dobrze. Token, który dostaje do autoryzacji muszę pobrać z usługi ponieważ wygasa co 5 minut
Napisałem dwie metody, które pobierają ten token, jedną za pomocą callback, a drugą z użyciem promise

   callToken(): Promise<any> {
    let url = 'url';
    let body = "body";
    let promise = fetch(url, {
      body: body,
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
      },
      method: 'POST',
    });

    return promise
      .then(resp => resp.json())
      .then(json => json.access_token);

  }
      callForToken(): string {
    let url = 'url';
    let body = 'body';

    let option = {
      headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded')
    };
    let token;
    this.http.post<Token>(url, body, option).subscribe(
      res => {
        token = res.access_token;
      }
    );
    return token;
  }

Przy wykorzystaniu promice dostaje w nagłówku screenshot-20180529210530.png
A jak chce skorzystać z callback to też nie wiem do końca jak to zrobić z uwagi na to, że jest to asynchroniczne zapytanie i nie mogę wyciągnąć wartości po za metodę.

W przypadku użycia promise jak wypisze sobie do konsoli ten token to jest prezentowany poprawnie, a jak chce umieścić w nagłówku to widać do wyżej.
Jakiś pomysł, na rozwiązanie ?

0

Abstrahując od głównego problemu, wykorzystywanie interceptora po to, żeby przy każdym requeście wysłać strzał po token jest jakimś nieporozumieniem.

Jeżeli jednak nie chcesz zmieniać tego co masz - mała podpowiedź. Logikę związaną z klonowaniem nagłówków i zwracaniem konkretnego obiektu Observable<HttpEvent<any>> powinieneś opakować w Promisa, który najpierw będzie bił po token.

0

Dla Twojego spokoju na tą chwilę jeszcze nie przygotowałem mechanizmu sprawdzania, czy token wygasł ale będzie to zrobione tak, że będę wołał token dopiero jak wygaśnie ( 5 minut ).
Jakie inne rozwiązanie proponujesz po za interceptorem na ten problem ?

0

Jeżeli twój token wygaśnie, będziesz musiał przeprowadzić cały proces autentykacji od początku. Nie jestem pewien czy rzeczywiście tego chcesz.
Korzystanie z interceptora nie jest dobrym wyjściem również dlatego, że bezczynność użytkownika przez więcej niż 5 min spowoduje automatyczne wygaśnięcie tokena.

Gdybym mógł implementować backend i frontend, wykorzystałbym web sockety i podejście https://en.wikipedia.org/wiki/Heartbeat_(computing)
Gdybym nie mógł implementować backendu to pewnie po stronie frontu napisałbym prosty serwis, który zajmowałby się odświeżaniem tokena (średnie rozwiązanie, ale nic lepszego nie przychodzi mi do głowy).

Może inni coś jeszcze doradzą.

0

No własnie jeżeli token wygaśnie to nie ma innego wyjścia tylko odświeżenie. Pamiętaj, że nie jest to token który używasz aby korzystać z serwisu, tylko po to aby wołać usługi, więc nawet jeżeli w trakcie przeglądania strony token wygaśnie to właśnie po to jest interceptor żeby sprawdzić przed wywołaniem usługi czy potrzeba jest odnowienia tokenu i ewentualnie to zrobić.

Hmm na heartbeatsach chciałbyś oprzeć autentykacje użytkownika w Twoim serwisie ? Opowiesz jak miałoby to działać ?
Akurat tu jesteśmy w sytuacji, że bierzemy całość z dobrodziejstwem inwentarza, więc mamy tylko front możliwy do zmiany.

1 użytkowników online, w tym zalogowanych: 0, gości: 1