Использование распознавателя с функциями защиты, не разрешенными с помощью вложенных наблюдаемых - PullRequest
0 голосов
/ 10 апреля 2019

У меня есть угловое ионное приложение, которое получает статьи из API.Эти статьи могут быть бесплатными или платными, требующими активного членства.Я использую распознаватель, чтобы убедиться, что статья существует, прежде чем перейти к маршруту.В этом преобразователе я также пытаюсь проверить, есть ли вошедший в систему пользователь и активен ли этот пользователь.При ведении журнала все работает, но маршрут не загружается, если вошел активный пользователь.Я думаю, что это как-то связано с неправильным вложением / отображением наблюдаемых объектов.

На моем AppUserService у меня есть идентификатор пользователя (который обозначает, что пользователь вошел в систему), настроенный как BehaviorSubject, чтобы я мог подписаться на измененияна нем.

import { Injectable } from '@angular/core';
import { Observable, BehaviorSubject } from 'rxjs';

import { IdentityInterface } from './../models/identity.interface'
/**
 * AppUserService is used app-wide to identify the current user of the app
 * This only related to any user modules or services that would be for
 * communicating with the API about user data insofar as the identity set
 * on this service should from data obtained by an external service for authenticating
 * and getting a user
 */
@Injectable({
    providedIn: 'root'
})
export class AppUserService {
    /**
     *
     */
    private identity = new BehaviorSubject<IdentityInterface>(null);
    public identity$ = this.identity.asObservable();

    private returnUrl: any = ["/home"];

    constructor() {
    }

    /**
     * "Logs" the user in which is essentially setting their identity
     */
    public login(identity: IdentityInterface){
        this.setIdentity(identity);
    }

    /**
     * "Logs" the user out which essentially just removes identity information from storage
     */
    public logOut(){
        this.setIdentity(null);
    }

    /**
     * Sets the identity member property and saves to storage
     */
    public setIdentity(identity): void{
        // --- Broadcast the setting of the identity on the identity subject so other
        // --- parts of the app subscribed to this can pick up on it
        this.identity.next(identity);
        this.saveIdentityToStorage(identity);
    }

    /**
     * Attempts to automatically log in a user based on identity data in localstorage
     */
    public attemptAutoLogin(){
        let identity = this.getIdentityFromStorage();
        if(identity !== null){
            this.login(identity);
        }
    }

    /**
     * Returns the URL the user should be sent to after successful login
     */
    public getReturnUrl(defaultUrl: any = null){
        return this.returnUrl;
    }

    /**
     * Returns the URL the user should be sent to after successful login
     */
    public setReturnUrl(url: any){
        this.returnUrl = url;
    }

    /**
     * Uses local storage to save identity data
     */
    private saveIdentityToStorage(identity){
        localStorage.setItem("identity", JSON.stringify(identity));
    }

    /**
     * Loads identity data from storage
     */
    private getIdentityFromStorage(){
        return JSON.parse(localStorage.getItem("identity"));
    }
}

В распознавателе я использую ArticleService для получения ответа от API, и если он найден и не свободен, пытается подписаться на удостоверение AppUserService, чтобы увидеть, есть ли в журналев пользователя.Это все работает, как и ожидалось

import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { Observable, of, EMPTY }  from 'rxjs';
import { map, switchMap, take }         from 'rxjs/operators';

import { AppUserService } from './../../../core/services/app-user.service';

import { Article } from './../models/article';
import { ArticleService } from './../services/article.service';
import { User } from './../../user/models/user';

/**
 * Make sure we have the Article data before loading the Article view page
 */
@Injectable({
  providedIn: 'root'
})
export class ArticleResolverService implements Resolve<Article> {

    constructor(
        private articleService: ArticleService,
        private appUserService: AppUserService,
        private router: Router
    ) {}

    resolve(
        route: ActivatedRouteSnapshot,
        state: RouterStateSnapshot
    ): Observable<Article> | Observable<never> {
        // --- Load the article from the API
        return this.articleService.read(parseInt(route.paramMap.get("id"))).pipe(
            take(1),
            switchMap(article => {
                if (article) {
                    console.log("article found");
                    // --- If it's not free do some auth checks
                    if(!article.free){
                        console.log("article is premium");
                        return this.appUserService.identity$.pipe(
                            map( result => {
                                let user = (!result ? null : result as User);
                                // -- If no user identity is set send them to login
                                if(!user){
                                    console.log("no user");
                                    this.appUserService.setReturnUrl([state.url]); // --- Router requires array
                                    this.router.navigate(['/user/login']);
                                    return EMPTY;
                                } else if(!user.active){
                                    console.log("user not active");
                                    this.router.navigate(['/subscribe']);
                                    return EMPTY;
                                } else {
                                    console.log("user is active");
                                    console.log(article);
                                    return of(article);
                                }
                            })
                        );
                    } else {
                        console.log("article is free");
                        return of(article);
                    }
                } else { // id not found
                    console.log("article not found");
                    this.router.navigate(['/article/list']);
                    return EMPTY;
                }
            })
        );
    }
}

Когда я пытаюсь получить доступ к бесплатной статье, она работает, как ожидалось, вне зависимости от того, вошел в систему или нет.Когда я пытаюсь получить доступ к премиальной статье, она перешлет мне, как ожидается, если нет пользователя или неактивного пользователя.Но когда есть активный, залогиненный пользователь, он не загружает маршрут.Он просто остается на той же странице, где страница статьи не загружается.Вот лог консоли, где я пробовал это.После регистрации объекта article на консоли он возвращает наблюдаемую статью, но не идет по маршруту, как ожидалось:


core.js:16829 Angular is running in the development mode. Call enableProdMode() to enable the production mode.
common.js:290 Native: tried calling StatusBar.styleDefault, but Cordova is not available. Make sure to include cordova.js or run in a device/simulator
common.js:290 Native: tried calling SplashScreen.hide, but Cordova is not available. Make sure to include cordova.js or run in a device/simulator
article-resolver.service.ts:35 article found
article-resolver.service.ts:60 article is free
core.js:11462 WARNING: sanitizing HTML stripped some content, see http://g.co/ng/security#xss
article-resolver.service.ts:35 article found
article-resolver.service.ts:38 article is premium
article-resolver.service.ts:44 no user
article-resolver.service.ts:35 article found
article-resolver.service.ts:38 article is premium
article-resolver.service.ts:53 user is active
article-resolver.service.ts:54 
Article {id: 3854, category_id: 107, format_id: 101, title: "Offseason Dynasty Refocus: TE", author: "Matt Schauf", …}
article-resolver.service.ts:35 article found
article-resolver.service.ts:60 article is free
core.js:11462 WARNING: sanitizing HTML stripped some content, see http://g.co/ng/security#xss
article-resolver.service.ts:35 article found
article-resolver.service.ts:38 article is premium
article-resolver.service.ts:53 user is active
article-resolver.service.ts:54 
Article {id: 3844, category_id: 107, format_id: 101, title: "Offseason Dynasty Refocus: Quarterback", author: "Matt Schauf", …}

Я предполагаю, что моя проблема заключается в том, что я не знаю, как правильно «свернуть»'наблюдаемые и убедитесь, что он правильно возвращает (статья) из вложенной наблюдаемой.Я прочитал много статей, но не могу понять это.Вот две соответствующие ссылки, которые я использовал:

https://blog.angular -university.io / rxjs-высший порядок отображения /

Angular2: вложенные наблюдаемыев карауле

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...