कोणीय 2 - रूटिंग - ऑब्जर्वेबल के साथ कार्य को सक्रिय कर सकता है


94

मेरे पास एक AuthGuard है (रूटिंग के लिए उपयोग किया जाता है) जो CanActivate को लागू करता है

canActivate() {
    return this.loginService.isLoggedIn();
}

- मेरी समस्या है, कि CanActivate-परिणाम एक http-get-परिणाम पर निर्भर करता है LoginService एक रिटर्न प्रत्यक्ष

isLoggedIn():Observable<boolean> {
    return this.http.get(ApiResources.LOGON).map(response => response.ok);
}

मैं उन लोगों को एक साथ कैसे ला सकता हूं - CanActivate एक बैकएंड राज्य पर निर्भर करते हैं?

# # # # # #

EDIT: कृपया ध्यान दें, यह प्रश्न 2016 से है - कोणीय / राउटर के एक बहुत ही प्रारंभिक चरण का उपयोग किया गया है।

# # # # # #


2
क्या आपने यहाँ पढ़ा है? angular.io/docs/ts/latest/guide/router.html रूट गार्ड के लिए खोजें यहां CanActivate के लिए एपीआई संदर्भ है: angular.io/docs/ts/latest/api/router/index/… जैसा कि आप देखते हैं कि यह या तो वापस आ सकता है बूलियन या
ऑब्जर्वेबल

4
canActivate()एक वापसी कर सकते हैं Observable, बस सुनिश्चित करें कि Observableपूरा हो गया है (यानी। observer.complete())।
फिलिप बुल्ले

1
@PhilipBulley क्या होगा अगर अवलोकनीय अधिक मूल्यों का उत्सर्जन करता है और फिर पूरा होता है? गार्ड क्या करता है? मैंने अब तक take(1)Rx ऑपरेटर का उपयोग स्ट्रीम को पूरा करने के लिए किया है, क्या होगा अगर मैं इसे जोड़ना भूल जाऊं?
फेलिक्स

जवाबों:


146

आपको "@ कोणीय / राउटर" को नवीनतम में अपग्रेड करना चाहिए। उदाहरण के लिए "3.0.0-alpha.8"

AuthGuard.ts को संशोधित करें

@Injectable()
export class AuthGuard implements CanActivate {
    constructor(private loginService:LoginService, private router:Router) { }

    canActivate(next:ActivatedRouteSnapshot, state:RouterStateSnapshot) {
        return this.loginService.isLoggedIn().map(e => {
            if (e) {
                return true;
            }
        }).catch(() => {
            this.router.navigate(['/login']);
            return Observable.of(false);
        });
    }   
}

यदि आपके कोई प्रश्न हैं, तो मुझसे पूछें,


3
यह इंगित करने योग्य है कि यह बहुत ही समान तरीके से वादों के साथ काम करता है। मेरे कार्यान्वयन के लिए, मान isLoggedIn()लेना एक है Promise, आप isLoggedIn().then((e) => { if (e) { return true; } }).catch(() => { return false; });उम्मीद कर सकते हैं कि इससे भविष्य के यात्रियों को मदद मिलेगी!
kbpontius

6
मुझे जोड़ना होगाimport 'rxjs/add/observable/of';
marc_aragones

1
एक अच्छा जवाब नहीं अब IMO .. यह सर्वर साइड क्या हो रहा है की कोई विवरण प्रदान करता है ... यह अल्फा में तारीख से बाहर है! ... यह इस सर्वोत्तम प्रथा का पालन नहीं करता है .. angular.io/docs/ts/latest/guide/… .. नीचे मेरा अद्यतन उत्तर देखें (उम्मीद है कि एक दिन ऊपर)
danday74

1
canActivate चाहिए retun नमूदार <बूलियन>
Yoav Schniederman

बड़ी मदद :) धन्यवाद
gschambial

57

एंगुलर 5 और आरएक्सजेएस 5.5 के लिए केरी हू के जवाब को अपडेट करना जहां catchऑपरेटर को पदावनत किया जाता है। अब आप पाइप के साथ संयोजन के रूप में catchError ऑपरेटर का उपयोग करना चाहिए और किराए पर देने ऑपरेटरों

import { Injectable } from '@angular/core';
import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { catchError, map} from 'rxjs/operators';
import { of } from 'rxjs/observable/of';

@Injectable()
export class AuthGuard implements CanActivate {

  constructor(private loginService: LoginService, private router: Router) { }

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean>  {
    return this.loginService.isLoggedIn().pipe(
      map(e => {
        if (e) {
          return true;
        } else {
          ...
        }
      }),
      catchError((err) => {
        this.router.navigate(['/login']);
        return of(false);
      })
    );
  }   

}

मेरे पास isLoggedIn () के बाद 1 और XHR कॉल है, और XHR का परिणाम 2nd XHR कॉल में उपयोग किया जाता है। 2 ajax कॉल कैसे करें जो 1 परिणाम के लिए स्वीकार करेगा? आपके द्वारा दिया गया उदाहरण बहुत आसान है, क्या आप मुझे पाइप () का उपयोग करने का तरीका बता सकते हैं यदि मेरे पास एक और अजाक्स भी है।
प्रतीकात्मक

9

canActivate ()Observable<boolean> लौटाए गए मान के रूप में स्वीकार करता है । गार्ड ऑब्जर्वेबल को हल करने और मूल्य को देखने के लिए इंतजार करेगा। यदि 'सही' है तो यह चेक को पास कर देगा, अन्यथा (कोई अन्य डेटा या फेंकी गई त्रुटि) मार्ग को अस्वीकार कर देगा।

आप का उपयोग करने के लिए .mapऑपरेटर को बदलने के Observable<Response>लिए उपयोग कर सकते हैं Observable<boolean>:

canActivate(){
    return this.http.login().map((res: Response)=>{
       if ( res.status === 200 ) return true;
       return false;
    });
}

1
कैच ब्लॉक के बारे में क्या? पकड़ ब्लॉक कहा जाता है अगर यह एक 401 सही है?
danday74

1
कोणीय 4 में काम नहीं करता है। यह कहीं न कहीं एक सामान्य प्रकार को परिभाषित करने की जरूरत है।
gtzinos

2

मैंने इसे इस तरह से किया है:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
return this.userService.auth(() => this.router.navigate(['/user/sign-in']));}

जैसा कि आप देख सकते हैं कि मैं userService.auth को फालबैक फंक्शन भेज रहा हूं, अगर http कॉल फेल हो जाए तो क्या करना चाहिए।

और उपयोगकर्ता सेवा में मेरे पास है:

import 'rxjs/add/observable/of';

auth(fallback): Observable<boolean> {
return this.http.get(environment.API_URL + '/user/profile', { withCredentials: true })
  .map(() => true).catch(() => {
    fallback();
    return Observable.of(false);
  });}

.map () फ़ंक्शन के मामले में वास्तव में अच्छा उत्तर - वास्तव में अच्छा :) - ने कॉलबैक कॉलबैक का उपयोग नहीं किया - इसके बजाय मैंने कैनवेट विधि में ऑब्जर्वेबल के लिए सब्स्क्राइब्ड किया - विचार के लिए बहुत बहुत धन्यवाद
danday74

0

यह आपकी मदद कर सकता है

import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { Select } from '@ngxs/store';
import { Observable } from 'rxjs';
import { map, take } from 'rxjs/operators';
import { AuthState } from 'src/app/shared/state';

export const ROLE_SUPER = 'ROLE_SUPER';

@Injectable()
export class AdminGuard implements CanActivate {

 @Select(AuthState.userRole)
  private userRoles$: Observable<string[]>;

  constructor(private router: Router) {}

 /**
   * @description Checks the user role and navigate based on it
   */

 canActivate(): Observable<boolean> {
    return this.userRoles$.pipe(
      take(1),
      map(userRole => {
        console.log(userRole);
        if (!userRole) {
          return false;
        }
        if (userRole.indexOf(ROLE_SUPER) > -1) {
          return true;
        } else {
          this.router.navigate(['/login']);
        }
        return false;
      })
    );
  } // canActivate()
} // class

-1

CanActivate ऑब्जर्वबल के साथ काम करता है, लेकिन विफल रहता है जब 2 कॉल Canctctivate की तरह किए जाते हैं: [Guard1, Guard2]।
यहाँ यदि आप Guard1 से अवलोकनीय को वापस लौटाते हैं, तो यह Guard2 में भी जाँच करेगा और यदि Guard2 सही है तो मार्ग की अनुमति देगा। उससे बचने के लिए, गार्ड 1 को बूलियन के अवलोकन के बजाय एक बूलियन वापस करना चाहिए।


-10

, canActivate () में, आप एक स्थानीय बूलियन प्रॉपर्टी (आपके मामले में झूठी) के लिए वापस कर सकते हैं।

private _canActivate: boolean = false;
canActivate() {
  return this._canActivate;
}

और फिर LoginService के परिणाम में, आप उस संपत्ति के मूल्य को संशोधित कर सकते हैं।

//...
this.loginService.login().subscribe(success => this._canActivate = true);

तुम प्रतिभाशाली हो, सर।
कीन गुयेन Ngoc
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.