Передача данных токена Oauth от сервиса к компоненту - Angular - PullRequest
0 голосов
/ 01 ноября 2018

Я пытаюсь выяснить, как передать пользовательский токен, который возвращается как часть неявной процедуры oauth2 в сервисе, компоненту, который является URL-адресом обратного вызова, чтобы я мог затем использовать этот токен в дальнейшем.

сервисный код

import { Injectable } from '@angular/core';
import {UserManager, UserManagerSettings, User} from 'oidc-client';

@Injectable({
  providedIn: 'root'
})
export class AuthService {
    private manager: UserManager = new UserManager(getClientSettings());
    private user: User = null;

  constructor() {
    this.manager.getUser().then(user => {
      this.user = user;
    });
  }

  isLoggedIn(): boolean {
    return this.user != null && !this.user.expired;
    }

  getClaims(): any {
  return this.user.profile;
    }

  getAuthorizationHeaderValue(): string {
      return `${this.user.token_type} ${this.user.access_token}`;
    }

  startAuthentication(): Promise<void> {
      return this.manager.signinRedirect();
    }

  completeAuthentication(): Promise<void> {
      return this.manager.signinRedirectCallback().then(user => {
        console.log(user.access_token);
          this.user = user;
      });
    }

}

export function getClientSettings(): UserManagerSettings {
  return {
    authority: 'https://someserver.com',
    client_id: 'clientid',
    redirect_uri: 'http://localhost:4200/auth-callback',
    post_logout_redirect_uri: 'http://localhost:4200/',
    response_type: "id_token token",
    scope: "openid read write",
    filterProtocolClaims: true,
    loadUserInfo: false,
    automaticSilentRenew: true,
    silent_redirect_uri: 'http://localhost:4200/silent-refresh.html'
  };
}

Используется библиотека OICD Oauth 2

код компонента ниже

import { Component, OnInit } from '@angular/core';
import { AuthService } from '../services/auth.service';
import { Router, NavigationCancel, ActivatedRoute } from '@angular/router';
import { URLSearchParams } from '@angular/http';
import { Http, RequestOptions, Headers, Response} from '@angular/http';

@Component({
  selector: 'app-auth-callback',
  templateUrl: './auth-callback.component.html',
  styleUrls: ['./auth-callback.component.css'],
  providers: [AuthService]
})
export class AuthCallbackComponent implements OnInit {
  public accesstoken:any;

  constructor(private http: Http, private router: Router, private authService: AuthService, private route: ActivatedRoute) {

   }

  ngOnInit() {
    this.authService.completeAuthentication();
  }

}

, как вы можете видеть, компонент успешно вызывает завершение аутентификации из сервиса при инициализации, однако я не могу понять, как передать user_token из сервиса в компонент. Вы увидите эту ссылку на токен в функции completeAuthentication службы, и в этот момент она успешно запишет журнал. На данный момент все, что я пытаюсь сделать, - это записать в консоль логин этого пользователя через компонент обратного вызова auth, чтобы показать, что он был передан правильно.

1 Ответ

0 голосов
/ 01 ноября 2018

Просто верните токен от completeAuthentication:

completeAuthentication(): Promise<string> {
  return this.manager.signinRedirectCallback().then(user => {
    console.log(user.access_token);
    this.user = user;
    return user.access_token;
  });
}

А в компонентном вызове:

ngOnInit() {
  this.authService.completeAuthentication().then(token => {
    console.log('Token in component:', token);
  });
}

Каким-то более элегантным и многократно используемым способом (чтобы другие компоненты тоже могли получить токен после его получения) было бы установить токен на BehaviorSubject в службе и подписаться на него из любого места.

Чтобы заставить это работать, в AuthService определите предмет, наблюдаемые и далее измените completeAuthentication:

export class AuthService {
  private manager: UserManager = new UserManager(getClientSettings());
  private user: User = null;
  private _token = new BehaviorSubject<string>(null);
  private _user = new BehaviorSubject<User>(null);
  ...
  get user$(): Observable<User> {
    return this._user.asObservable().pipe(
      filter(val => val !== null),
      distinctUntilChanged(),
      share());
  }

  get token$(): Observable<string> {
    return this._token.asObservable().pipe(
      filter(val => val !== null),
      distinctUntilChanged(),
      share());
  }

  completeAuthentication(): Promise<string> {
    return this.manager.signinRedirectCallback().then(user => {
      console.log(user.access_token);
      this.user = user;
      this._user.next(user);
      this._token.next(user.access_token);
      return user.access_token;
    });
  }
  ....
}

_token и _user являются BehaviorSubject , который содержит значение для соответствующих объектов.

token$ и user$ - Наблюдаемые потоки токена и пользователя соответственно. Они фильтруются (оператором filter), чтобы не возвращать никакого значения, если оно null. Если вы хотите получить null как знак того, что пользователь, например, не вошел в систему, просто закомментируйте эти строки.

В любом месте вашего кода, предполагая, что вы вводите службу, просто используйте наблюдаемое, чтобы получить последнее значение:

constructor(private authService: AuthService) {
  this.authService.token$.subscribe(token => {
    console.log('Got my token', token);
  });

  this.authService.user$.subscribe(user => {
    console.log('Got my user', user);
  });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...