5

tôi hiện đang triển khai một ứng dụng ví dụ angular2 với khởi động mùa xuân làm phụ trợ. Tôi đang gặp một số vấn đề với cơ chế bảo vệ giao diện người dùng và các quan sát.Angular2 auth guard với yêu cầu và quan sát http

tôi đang cố gắng để đạt được:

  1. khi ai đó đi vào một con đường bảo vệ bảo vệ auth nên kiểm tra nếu người dùng đã được thiết lập trong biến dịch vụ auth
  2. nếu nó không được thiết lập sau đó một http yêu cầu phải được phát hành để kiểm tra xem phiên có sẵn
  3. phương thức dịch vụ phải trả về giá trị true/false (không đồng bộ do yêu cầu http có thể không)
  4. nếu dịch vụ trả về sai trình bảo vệ sẽ chuyển hướng đến trang đăng nhập
  5. auth bảo vệ nên trở về đúng/sai nên các tuyến đường hoặc có thể được kích hoạt hay không

Mã của tôi hiện nay trông như thế này (tôi đang sử dụng RC5 btw.):

Auth Guard

import {Injectable} from "@angular/core"; 
import {CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router} from "@angular/router"; 
import {Observable, Subject} from "rxjs/Rx"; 
import {AuthService} from "./auth.service"; 

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

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean { 
    var authenticated = this.authService.isAuthenticated(); 
    var subject = new Subject<boolean>(); 
    authenticated.subscribe(
     (res) => { 
      console.log("onNext guard: "+res); 
      if(!res && state.url !== '/signin') { 
      console.log("redirecting to signin") 
      this.router.navigate(['/signin']); 
      } 
      subject.next(res); 
     }); 
    return subject.asObservable(); 
    } 
} 

Dịch vụ Auth

import {Injectable} from "@angular/core"; 
import {User} from "./user.interface"; 
import {Router} from "@angular/router"; 
import {Http, Response, Headers} from "@angular/http"; 
import {environment} from "../environments/environment"; 
import {Observable, Observer, Subject} from "rxjs/Rx"; 

@Injectable() 
export class AuthService { 
    private authenticatedUser : User; 
    constructor(private router: Router, private http: Http) {} 

    signupUser(user: User) { 
    } 


    logout() { 
    //do logout stuff 
    this.router.navigate(['/signin']); 
    } 

    isAuthenticated() : Observable<boolean> { 
    var subject = new Subject<boolean>(); 
    if (this.authenticatedUser) { 
     subject.next(true); 
    } else { 
     this.http.get(environment.baseUrl + '/user') 
     .map((res : Response) => res.json()) 
     .subscribe(res => { 
      console.log("next: returning true"); 
      this.authenticatedUser = User.ofJson(res); 
      subject.next(true); 
     }, (res) => { 
      console.log("next: returning false"); 
      subject.next(false); 
     }); 
    } 
    return subject.asObservable(); 
    } 
} 

vấn đề là: các bảo vệ không bao giờ cho phép thành phần bộ định tuyến kích hoạt, ngay cả khi tôi đăng nhập.

Cảm ơn sự giúp đỡ!

+0

Sự cố là gì? –

+0

xem chỉnh sửa, thành phần router không bao giờ kích hoạt, ngay cả khi tôi đăng nhập thành công. Nếu tôi không sử dụng bất kỳ quan sát nào thì nó hoạt động tốt, nhưng tôi không thể sử dụng các yêu cầu http vì vậy đó không phải là một lựa chọn cho tôi. – Tim

Trả lời

7

Thay đổi

return subject.asObservable(); 

để

return subject.asObservable().first(); 

Router đợi cho quan sát để hoàn thành. first() làm cho nó hoàn thành sau sự kiện đầu tiên.

+0

Cảm ơn điều này giải quyết một phần của vấn đề. Điều gì xảy ra bây giờ là khi tôi bấm vào một tuyến đường được bảo vệ nó luôn luôn ngăn chặn các tuyến đường từ kích hoạt và in thông điệp tường trình. Nhưng khi tôi nhập thông tin xác thực hợp lệ trong màn hình đăng nhập và máy chủ trả lời với 200 OK, tôi vẫn không thể truy cập tuyến đường được bảo vệ. Khi tôi nhấn f5 và làm mới trang tôi đột nhiên có thể truy cập tuyến đường được bảo vệ. Điều này có lẽ là do biến authenticatedUser trong lớp dịch vụ nơi tôi lưu trữ đối tượng người dùng, nhưng tôi không chắc chắn tại sao, bất kỳ ý tưởng nào? – Tim

+1

Bạn có thể thử dùng 'BehaviorSubject' thay cho' Subject' trong 'isAuthenticated()'. Hiện tại nếu 'this.authenticatedUser' là' true' bạn phát ra 'true' nhưng tại thời điểm này thì chưa có người đăng ký nào. Phần mã này được thực hiện đồng bộ và 'true' được phát ra trước khi' return subject.asObservable() 'được thực hiện và người gọi' isAuthenticated() 'sẽ không nhận được sự kiện này. –

+2

Tôi đã phải sử dụng kết hợp BehavorSubject (Service) và ReplaySubject (guard), nhưng nó hoạt động như mong đợi. Cảm ơn! – Tim

Các vấn đề liên quan