[英]Angular 11 You provided 'undefined' where a stream was expected
[英]Angular You provided 'undefined' where a stream was expected
請幫忙。 當從攔截器調用 refreshAccessToken 時會發生此錯誤。但代碼執行仍在繼續。
錯誤類型錯誤:您在預期 stream 的位置提供了“未定義”。 您可以提供 Observable、Promise、ReadableStream、Array、AsyncIterable 或 Iterable。
這是 http 攔截器,它在時間過去時調用刷新令牌。
import {Injectable} from '@angular/core';
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
import {Observable} from 'rxjs';
import {AuthService} from "../../../services/auth.service";
import {SharedService} from "../../../services/shared.service";
import * as moment from "moment";
@Injectable()
export class HttpInterceptorInterceptor implements HttpInterceptor {
constructor(private sharedService: SharedService, private authService: AuthService) {
}
putTokenInRequest(request: HttpRequest<any>, access_token: any): HttpRequest<any> {
return request = request.clone({
setHeaders: {
Authorization: `Bearer ${access_token}`
}
})
}
excludeRequest(request: HttpRequest<any>): boolean {
let request_to_exclude = [
"/protocol/openid-connect/token"
]
let exclude = false
for (let req of request_to_exclude) {
if (request.url.toString().includes(req)) {
exclude = true
}
}
return exclude;
}
intercept(request: HttpRequest<any>, next: HttpHandler) :any{
if (this.excludeRequest(request) != true) {
//before every request check if access token has expired
let access_token_expire_date = localStorage.getItem("access_token_expire_date")
//subtract 10 sc for safety
if (moment().isAfter(moment(access_token_expire_date).subtract(10, 's'))) {
console.log("access_token_expired")
let refreshToken = localStorage.getItem("refresh_token")
this.authService.refreshAccessToken(refreshToken).subscribe(response => {
localStorage.setItem("refresh_token", response.refresh_token)
localStorage.setItem("access_token", response.access_token)
let access_token_expire_date = moment().add(response.expires_in, 's')
let refresh_expire_date = moment().add(response.refresh_expires_in, 's')
localStorage.setItem('access_token_expire_date', access_token_expire_date.toString())
localStorage.setItem('refresh_expire_date', refresh_expire_date.toString())
return next.handle(this.putTokenInRequest(request, response.access_token))
})
} else {
//if access_token is active again.
let access_token = localStorage.getItem('access_token')
return next.handle(this.putTokenInRequest(request, access_token))
}
}
else {
//if request is excluded from interception just move on and don,t change it.
return next.handle(request);
}
}
}
服務
import {Injectable} from '@angular/core';
import {HttpClient, HttpHeaders, HttpParams} from "@angular/common/http";
import {environment} from "../../environments/environment";
import {Observable} from "rxjs";
@Injectable({
providedIn: 'root'
})
export class AuthService {
keyckloakUrl
baseUrl
constructor(private http: HttpClient) {
this.keyckloakUrl = environment.keyckloakUrl;
this.baseUrl = environment.baseUrl;
}
getExccessToken(code: any): Observable<any> {
const params = new HttpParams({
fromObject: {
client_id: 'authorization_code_grant_type',
grant_type: 'authorization_code',
code: code,
redirect_uri:'http://localhost:4200/dashboard/token_redirect'
}
});
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/x-www-form-urlencoded',
})
};
return this.http.post(`${this.keyckloakUrl}/realms/master/protocol/openid-connect/token`, params.toString(),httpOptions);
}
// logout():Observable<any>{
// return this.http.get(` http://localhost:8088/auth/realms/master/protocol/openid-connect/logout?redirect_uri=http://localhost:4200`);
// }
refreshAccessToken(refreshToken:any):Observable<any>{
// const params = new HttpParams({
// fromObject: {
// client_id: 'authorization_code_grant_type',
// grant_type: 'refresh_token',
// refresh_token: refreshToken,
// }
// });
// const httpOptions = {
// headers: new HttpHeaders({
// 'Content-Type': 'application/x-www-form-urlencoded',
// })
// };
let body = new URLSearchParams();
body.set('client_id', 'authorization_code_grant_type');
body.set('grant_type', 'refresh_token');
body.set('refresh_token', refreshToken);
let options = {
headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded')
};
debugger
return this.http.post<any>(`${this.keyckloakUrl}/realms/master/protocol/openid-connect/token`, body.toString(),options);
}
logout():Observable<any>{
return this.http.post(`${this.baseUrl}/logout`,{})
}
}
根據Angular 官方文檔,這是一個正確的interceptor
接口
interface HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>
}
您正在將intercept
的返回類型修改為any
並丟失了所有types safety
。
intercept(request: HttpRequest<any>, next: HttpHandler) :any
如果您不這樣做,任何體面的代碼編輯器都會為您突出顯示問題。
如果你看看這個代碼塊:
if (moment().isAfter(moment(access_token_expire_date).subtract(10, 's'))) {
console.log("access_token_expired")
let refreshToken = localStorage.getItem("refresh_token")
this.authService.refreshAccessToken(refreshToken).subscribe(response => {
localStorage.setItem("refresh_token", response.refresh_token)
localStorage.setItem("access_token", response.access_token)
let access_token_expire_date = moment().add(response.expires_in, 's')
let refresh_expire_date = moment().add(response.refresh_expires_in, 's')
localStorage.setItem('access_token_expire_date', access_token_expire_date.toString())
localStorage.setItem('refresh_expire_date', refresh_expire_date.toString())
return next.handle(this.putTokenInRequest(request, response.access_token))
})
您沒有為intercept
function 返回任何內容, return next.handle(this.putTokenInRequest(request, response.access_token))
在您的subscribe
回調中,因此您返回的內容基本上是void
或undefined
所以你所要做的就是返回stream
代替:
...
let refreshToken = localStorage.getItem('refresh_token');
return this.authService.refreshAccessToken(refreshToken).pipe(
map((response) => {
localStorage.setItem('refresh_token', response.refresh_token);
localStorage.setItem('access_token', response.access_token);
let access_token_expire_date = moment().add(response.expires_in, 's');
let refresh_expire_date = moment().add(
response.refresh_expires_in,
's'
);
localStorage.setItem(
'access_token_expire_date',
access_token_expire_date.toString()
);
localStorage.setItem(
'refresh_expire_date',
refresh_expire_date.toString()
);
return next.handle(
this.putTokenInRequest(request, response.access_token)
);
})
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.