我是Angular的新手,我试图将令牌从Spotify API传递到Angular中的服务方法,所以我有一个获取令牌并可以工作的端点,但是当我调用getQuery()方法时,输出标头的对象类似于:
{
Authorization: Bearer undefined
}
因此,当我要发出请求时,由于我的访问令牌不正确,它会抛出401状态。
这是我的服务和构造方法的样子:
import { Injectable } from '@angular/core';
import { HttpClient,HttpHeaders } from '@angular/common/http';
import { map } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class SpotifyService {
private token:string
constructor(
private http:HttpClient,
) {
const clientId = 'my client id';
const clientSecret = 'my client secret';
this.getToken(clientId, clientSecret);
}
这是我的getToken()方法的样子:
getToken(clientId:string, clientSecret:string){
const urlRequest = `https://myendpoint/${clientId}/${clientSecret}`;
this.http.get(urlRequest)
.subscribe( (data:any) =>{
this.token = data.access_token;
});
}
此时一切正常,但是当我从组件调用此服务并调用另一个服务方法时,构造函数似乎未执行,因为在此服务方法上出现了未定义的问题:
getQuery( query:string ){
const url = `https://spotifyapi/${query}`;
const headers = new HttpHeaders({
'Authorization': `Bearer ${this.token}`
});
console.log(headers);
return this.http.get(url,{headers});
}
我使用console.log()
来检查是否在getToken()中获取令牌,并且该令牌有效,但是似乎无法从getQuery()
方法访问它。
我只想通过该方法访问令牌,以便发出请求。
答案 0 :(得分:0)
好吧,我发现您尝试解决问题的方式存在一些问题。正如评论中指出的那样,在进行调用之前可能未获取令牌。 考虑进行以下更改
答案 1 :(得分:0)
由于
this.http.get
是一个异步呼叫,因此您应该等待直到呼叫结束。您可以根据实现方式来使用它:
@Injectable({ providedIn: 'root' })
export class SpotifyService {
// Changing its type from a simple string to an Observable<string>
private token$: Observable<string>;
constructor(private http:HttpClient) {
const clientId = 'my client id';
const clientSecret = 'my client secret';
// Initialize the token
this.token = this.getToken(clientId, clientSecret);
}
getToken(clientId:string, clientSecret:string): Observable<any> {
const urlRequest = `https://myendpoint/${clientId}/${clientSecret}`;
// Call the token api and get only its "access_token"
return this.http.get(urlRequest).pipe(map(data => data.access_token));
}
getQuery( query:string ){
const url = `https://spotifyapi/${query}`;
// Subscribe to the token$ observable and assign the token on your headers
this.token$.subscribe(token => {
const headers = new HttpHeaders({ 'Authorization': `Bearer ${this.token}` });
console.log(headers);
return this.http.get(url, {headers});
});
}
}
另一种方法是使用 HTTP拦截器
1。)登录后,通常它将为您提供令牌。将该令牌存储在您的localStorage中
localStorage.setItem('token:id', token);
2。)创建auth.interceptor.ts
有了这个,每次您调用API时,它将自动插入标头
@Injectable({ providedIn: 'root' })
export class AuthInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const token = localStorage.getItem('token:id');
if (token) {
const cloned = req.clone({ headers: req.headers.set('Authorization', `Bearer ${token}`) });
return next.handle(cloned);
}
else return next.handle(req);
}
}
3。)将其导入您的AppModule
或CoreModule
(如果有)
@NgModule({
imports: [],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi: true
}
]
})
export class AppModule {}