Ionic Storage Async

Discussão em 'Angular' iniciado por user28147072, Novembro 5, 2024.

  1. user28147072

    user28147072 Guest

    I have a problem: I want to replace Angular's localStorage with the Ionic Storage package, but it's asynchronous, which disrupts my entire code. Currently, I retrieve the token using the signal store, then I create a session that stores the token in localStorage. I also manage my isAuthenticated state with a getSessions to maintain that state when the page is refreshed.

    Additionally, I have a jwtInterceptor that puts the token in the header with the line const token = localInfra.getSession().access_token;. Here is the base code, but when I use the Ionic Storage package, it being asynchronous breaks my code.

    Ngrx Signal Store:

    export const AuthenticationStore = signalStore(
    { providedIn: 'root' },
    withState(initialValue),
    withComputed((store) => ({
    isLogged: computed(() => store.isAuthenticated()),
    isNotLogged: computed(() => !store.token() || !store.isAuthenticated()),
    })),
    withMethods(
    (
    store,
    infra = inject(AuthenticationInfrastructure),
    localInfra = inject(LocalStorageAuthenticationInfrastructure),
    router = inject(Router)
    ) => ({
    localLogin(token: WithToken): void {
    if (token.access_token) {
    patchState(store, {
    isAuthenticated: true,
    token: {
    access_token: token.access_token,
    expires_in: 0,
    refresh_expires_in: 0,
    refresh_token: '',
    },
    });
    }
    },
    logIn: rxMethod<AuthenticateType>(
    pipe(
    tap(() => patchState(store, { isLoading: true })),
    concatMap((input) => {
    return infra.login(input.login, input.password).pipe(
    map((tokenResponse) => {
    return {
    access_token: tokenResponse.access_token,
    expires_in: tokenResponse.expires_in,
    refresh_expires_in: tokenResponse.refresh_expires_in,
    refresh_token: tokenResponse.refresh_token,
    } as AuthenticationToken;
    }),
    tap((token) =>
    localInfra.startSession({
    access_token: token.access_token,
    refresh_token: token.refresh_token,
    })
    ),
    tapResponse({
    next: (token) => {
    patchState(store, {
    isLoading: false,
    isAuthenticated: true,
    token: token,
    });
    },
    error: () => {
    patchState(store, { isLoading: false });
    },
    })
    );
    })
    )
    ),
    logout: () => {
    patchState(store, {
    token: undefined,
    isLoading: false,
    isAuthenticated: false,
    });
    localInfra.endSession();
    router.navigateByUrl('login');
    },
    })
    ),
    withHooks({
    onInit(
    store,
    localInfra = inject(LocalStorageAuthenticationInfrastructure)
    ) {
    const userWithToken = localInfra.getSession();
    if (userWithToken.access_token) {
    store.localLogin(userWithToken);
    }
    },
    })
    );



    LocalStorage :

    export class LocalStorageAuthenticationInfrastructure {



    startSession(user: WithToken): void {
    if (user.access_token && user.refresh_token) {
    localStorage.setItem('access_token', user.access_token);
    localStorage.setItem('refresh_token', user.refresh_token);
    }
    }
    getSession(): WithToken {
    return {
    access_token: localStorage.getItem('access_token'),
    refresh_token: localStorage.getItem('refresh_token'),
    };
    }
    endSession(): void {
    localStorage.removeItem('id_token');
    }
    }


    JwtInterceptor :

    export function jwtInterceptor(req: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>> {

    const localInfra = inject(LocalStorageAuthenticationInfrastructure);
    const token = localInfra.getSession().access_token;

    if (!token) {
    return next(req)
    }

    const headers = new HttpHeaders({
    Authorization: `Bearer ${token}`
    })

    const newReq = req.clone({
    headers
    })

    return next(newReq)
    }


    I've modified my getSessions method :

    async getSession(): Promise<WithToken> {
    return {
    access_token: await this.ionicStorage.get('access_token'),
    refresh_token: await this.ionicStorage.get('refresh_token'),
    };
    }


    I'm returning a Promise. However, how can I now retrieve the token with getSessions in my jwtInterceptor, since it's asynchronous? Also, my SignalStore is no longer working:

    withHooks({
    onInit(
    store,
    localInfra = inject(LocalStorageAuthenticationInfrastructure)
    ) {
    const userWithToken = localInfra.getSession();
    if (userWithToken.access_token) {
    store.localLogin(userWithToken);
    }
    },
    })


    I'm a beginner, sorry if I'm doing things incorrectly.

    Continue reading...

Compartilhe esta Página