我试图弄清楚如何将用户令牌作为服务中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();
}
}
如您所见,组件在init上成功从服务调用了completeAuthentication,但是我不知道如何将user_token从服务传递到组件。您将在该服务的completeAuthentication功能中看到此令牌引用,并且它确实可以成功地控制台日志。目前,我要做的只是通过auth回调组件控制台记录该用户令牌,以显示其正确传递。
答案 0 :(得分:0)
只需从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
作为未登录用户的标志,只需注释掉这些行。
在代码中的任何地方(假设您注入了服务),只需使用Observable即可获取最新值:
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);
});
}