Poruszałem się na głowę na wiele godzin i mam nadzieję, że ktoś może mi pomóc i poprowadzi mnie. W ten sposób opracowuję moduł uwierzytelniania aplikacji kątowej 7. Jednym z wymagań jest opracowanie interceptora HTTP, aby dodać token autoryzacji (JWT), a także do obsługi wszystkich komunikatów o błędach.

Używam pakietu NPM, aby obsłużyć Localstorage tokens. Ten pakiet używa zestawu i uzyskać metody przechowywania i zwraca obietnicę, a nie rzeczywistą wartość tokena.

Teraz mój problem jest w mojej funkcji przechwytującej, jak widać poniżej. Próbowałem skomentować, gdzie się utknę.

intercept(request: HttpRequest<any>, next: HttpHandler): 
    Observable<HttpEvent<any>> {

    // Trying to get the token here but this returns a promise
    // this.token is a service for managing storage and retrieving of tokens
    const token = this.token.getToken();

    // If token is got, set it in the header
    // But when i console log, i see [object promise] other than the token
    if (token) {
        request = request.clone({
            headers: request.headers.set('Authorization', 'Bearer ' + token)
        });
    }

    return next.handle(request).pipe(catchError(err => {
        // Logs out the user if 401 error
        if (err.status === 401) {
            this.token.remove()
                .then(() => {
                    this.auth.changeAuthStatus(false);
                    this.router.navigateByUrl('/login');
                });
        }

        // Returns the error message for the user to see
        // for example in an alert
        const error = err.error.message || err.statusText;
        return throwError(error);
    }));
}

Mam nadzieję, że dobrze wyjaśniłem ten problem. Próbowałem użyć async przed funkcją przechwytującej, ale otrzymuję czerwony paskudny błąd mówiący TS1055: Type 'typeof Observable' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value.   Types of parameters 'subscribe' and 'executor' are incompatible..

Doceniam jakąkolwiek pomoc w naprawie tego problemu.

Dziękuję Ci!

0
realnsleo 22 luty 2019, 02:48

2 odpowiedzi

Najlepsza odpowiedź

Aby włączyć przetwarzanie asynchronicznego do przechwytującego, chcesz promować obietnicę obserwowalni, a switchMap Twoje obserwownienia razem, zwracając odpowiednie żądanie:

import { from as observableFrom } from "rxjs";
import { switchMap } from "rxjs/operators";

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return observableFrom(this.token.getToken()).pipe(
        switchMap(token => {

            // do something with your promise-returned token here

            return next.handle(request).pipe(catchError(err => {
                // Logs out the user if 401 error
                if (err.status === 401) {
                    this.token.remove()
                        .then(() => {
                            this.auth.changeAuthStatus(false);
                            this.router.navigateByUrl('/login');
                        });
                }

                // Returns the error message for the user to see
                // for example in an alert
                const error = err.error.message || err.statusText;
                return throwError(error);
            }));
        })
    );
}

Nie przetestowałem tego kodu bezpośrednio, więc przepraszam za jakiekolwiek literówki, ale powinno to doprowadzić, gdzie chcesz iść.

1) Promuj obietnicę obserwowalną z from

2) Odzyskaj obserwowały za pomocą switchMap

Zauważam, że nie używasz tokena zwróconego w swoim przykładzie, zrobiłbyś to w funkcji w ramach programu Switchmap, który otrzymuje wynik obietnicy

3
derelict 22 luty 2019, 01:08

Spróbuj wziąć token bezpośrednio z lokalnego przechowywania. W tym celu otrzymasz token przechowywać ten token do lokalnego przechowywania przy użyciu metody usługi token.

Wypróbuj poniższy kod:

Token.service.ts.

setToken(token) {
    localStorage.setItem('app-token', JSON.stringify(token));
}

getToken() {
    return JSON.parse(localStorage.getItem('app-token'));
}

Kodeks interceptora.

intercept(request: HttpRequest<any>, next: HttpHandler): 
Observable<HttpEvent<any>> {

//This token is retrieved from local storage
const token = this.token.getToken();

// If token is got, set it in the header
// But when i console log, i see [object promise] other than the token
if (token) {
    request = request.clone({
        headers: request.headers.set('Authorization', 'Bearer ' + token)
    });
}

return next.handle(request).pipe(catchError(err => {
    // Logs out the user if 401 error
    if (err.status === 401) {
        this.token.remove()
            .then(() => {
                this.auth.changeAuthStatus(false);
                this.router.navigateByUrl('/login');
            });
    }

    // Returns the error message for the user to see
    // for example in an alert
    const error = err.error.message || err.statusText;
    return throwError(error);
}));
}
0
Zarna Borda 22 luty 2019, 04:08