授权不记名令牌 Angular 5
Authorization bearer token Angular 5
我很困惑如何在 Angular 5 中为简单的 Get 请求创建一个好的 header。
这就是我需要在 Angular 中做的事情:
这是我目前所拥有的:
getUserList(): Observable<UserList[]> {
const headers = new Headers();
let tokenParse = JSON.parse(this.token)
headers.append('Authorization', `Bearer ${tokenParse}`);
const opts = new RequestOptions({ headers: headers });
console.log(JSON.stringify(opts));
const users = this.http.get<UserList[]>(this.mainUrl, opts)
return users
.catch(this.handleError.handleError);
}
这是我 console.log 中的回复:
{"method":null,"headers":{"Authorization":["Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImYwODZlM2FiYTk0ZjVhMjVmNDhiNzlkYmI2YWUwOWY4YzE2MTUyMzg2N2I5MDZiY2MzNWQyNWJiYTZmYTE4YjEwZjA1MjZiNThkZjE2Y2FjIn0.eyJhdWQiOiJmMDExY2M1OC00MGNlLTQzYTktOGY3MS04NDI0OTRlM2E5OTciLCJqdGkiOiJmMDg2ZTNhYmE5NGY1YTI1ZjQ4Yjc5ZGJiNmFlMDlmOGMxNjE1MjM4NjdiOTA2YmNjMzVkMjViYmE2ZmExOGIxMGYwNTI2YjU4ZGYxNmNhYyIsImlhdCI6MTUyMzU1MTQ0NSwibmJmIjoxNTIzNTUxNDQ1LCJleHAiOjE1MjM1NTQ0NDUsInN1YiI6IjIiLCJzY29wZXMiOlsiYXV0aGVudGljYXRlZCIsImFuZ3VkcnUiXX0.E-WdQTl7nPDW0gj0rohfql-QgnAinzvDxPR-pySMrG07XFY9tA6Ex7IL23pDBmKDmQO8RcZKa0L5r6SRQq9_iqzMWzn5Zxp94J9TJrpZ2KGMoLR_FbK_tpC5G5q5vUnCe3q34sH7cPdT_2cI704OWWaYmIUKKpXWUIG0PJw_uKSJ_uOifPv59RZGQkoaQ9gPywDKe-uamm1Faug-Kk2YnFMoEJq7ou19zyxgdpX80ZTPUae67uB0PGLRuvxfGaqVsJ8k0NunAY3-pyUnBwR_3eeuOxf4TyfW2aiOJ9kuPgsfV4Z1JD7nMpNtTHMJaXEyNkBW8RlYHD1pj4dkdnsDmw"]},"body":null,"url":null,"withCredentials":null,"responseType":null}
看起来很漂亮。但是给我这个错误
GET http://druang.dd:8080/user-list?_format=json 403 (Forbidden)
还有一条线索可以解开这个谜团。在 Sublime 文本中,如果我将鼠标放在 opts
上,它会显示如下内容:
ERROR in src/app/services/userlist.service.ts(33,59): error TS2345:
Argument of type 'RequestOptions' is not assignable to parameter of
type '{ headers?: HttpHeaders | { [header: string]: string | string[];
}; observe?: "body"; params?: Ht...'. Types of property 'headers'
are incompatible.
Type 'Headers' is not assignable to type 'HttpHeaders | { [header: string]: string | string[]; }'.
Type 'Headers' is not assignable to type '{ [header: string]: string | string[]; }'.
Index signature is missing in type 'Headers'.
有什么想法吗??
这是完整的 Git repo
感谢您的帮助!
两件事:
headers.append(...)
不会改变 header 的 object,因此您的授权 header 不会被发送。你需要做 headers = headers.append(...)
尝试this.http.get<UserList[]>(this.mainUrl, { headers: headers });
我不是很擅长编程,但有一点尝试和失败
如果找到这个:
getUserList(): Observable<UserList[]> {
let tokenParse = JSON.parse(this.token)
// let myHeaders = new Headers();
// myHeaders.set('Authorization', `Bearer ${tokenParse}`);
// let options = new RequestOptions({ headers: myHeaders});
const users = this.http.get<UserList[]>(this.mainUrl, { headers:new HttpHeaders().append('Authorization', `Bearer ${tokenParse}`)})
// const users = this.http.get<UserList[]>(this.mainUrl, options);
return users
.catch(this.handleError.handleError);
}
我使用 .set
还是 .append
并不重要,归根结底,这两种情况都有效...
我真的不知道发生了什么,所以,如果有人想在评论中解释它,欢迎您...
我建议使用 HttpInterceptor
为传出请求设置默认 HTTP header,而不是向每个调用添加额外的 HTTP header。
HTTP Client - Setting default headers @ angular.io
在您的示例中,您可以执行以下操作:
import { Http, Headers, Response } from '@angular/http';
getLoggedInUser(auth_token): Observable<any> {
const headers = new Headers({
'Content-Type': 'application/json',
'Authorization': `Bearer ${auth_token}`
})
return this.http.get(apiUrl, { headers: headers })
}
对于 get
请求,我使用了以下代码并且有效
import { HttpClient, HttpHeaders } from '@angular/common/http';
getServerList(){
var reqHeader = new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + JSON.parse(localStorage.getItem('mpManagerToken'))
});
return this.http.get<Server[]>(`${environment.apiUrl}/api/Servers/GetServerList`, { headers: reqHeader });
}
在Angular6和7中,该方法可用于拦截所有HTTP请求并添加bearer token。
此处提供了实施教程。 Youtube,这个频道有所有的教程。
拦截器组件
import {
HttpInterceptor,
HttpRequest,
HttpHandler,
HttpUserEvent,
HttpEvent
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { UserService } from '../shared/user.service';
import { tap } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private router: Router) {}
intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
if (req.headers.get('No-Auth') === 'True') {
return next.handle(req.clone());
}
if (localStorage.getItem('userToken') != null) {
const clonedreq = req.clone({
headers: req.headers.set(
'Authorization',
'Bearer ' + localStorage.getItem('userToken')
)
});
return next.handle(clonedreq).pipe(
tap(
succ => {},
err => {
if (err.status === 401) {
// this.router.navigateByUrl('/login');
} else if ((err.status = 403)) {
// this.router.navigateByUrl('/forbidden');
// alert(err.localStorage.getItem('userToken'));
}
}
)
);
} else {
this.router.navigateByUrl('/login');
}
}
}
保护组件
import { Injectable } from '@angular/core';
import {
CanActivate,
ActivatedRouteSnapshot,
RouterStateSnapshot,
Router
} from '@angular/router';
import { Observable } from 'rxjs';
import { UserService } from '../shared/user.service';
import { ToastrService } from 'ngx-toastr';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(
private router: Router,
private userService: UserService,
private toastr: ToastrService
) {}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): boolean {
if (localStorage.getItem('userToken') != null) {
const roles = next.data['roles'] as Array<string>;
if (roles) {
const match = this.userService.roleMatch(roles);
if (match) {
return true;
} else {
// tslint:disable-next-line: quotemark
this.toastr.info("You don't have access to this page");
this.router.navigate(['/login']);
// this.router.navigate(['/forbidden']);
return false;
}
} else {
return true;
}
}
this.router.navigate(['/login']);
return false;
}
}
将其添加到 app.modules.ts
providers: [
ConfirmationDialogService,
UserService,
DoctorService,
{ provide: OwlDateTimeIntl, useClass: DefaultIntl },
{ provide: OWL_DATE_TIME_FORMATS, useValue: MY_MOMENT_FORMATS },
AuthGuard,
{
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi: true
}
],
然后把守卫加到route
{
path: 'adminPanel',
component: AdminPanelComponent,
canActivate: [AuthGuard],
data: { roles: ['Admin'] }
},
'Authorization': 'Bearer ' + access_token,
有效
虽然@HassanRahman 为 get
个请求显示它,但对于 post
个请求,
import { HttpClient, HttpHeaders } from '@angular/common/http';
getServerList(){
postData = { your data }
var reqHeader = new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + JSON.parse(localStorage.getItem('mpManagerToken'))
});
return this.http.post<Server[]>(`${environment.apiUrl}/api/Servers/GetServerList`, postData, { headers: reqHeader });
}
我已经使用了上述所有建议的格式来附加带有访问令牌的 headers,它在请求 header 中添加空值,如“Authorization Bearer null”。
如果我在 adding/cloning headers 行之前打印 accesstoken,accesstoken 值将打印在浏览器控制台中。这是我使用的格式。
console.log("Inside Interceptor accesstoken : " + this.oauthService.getAccessToken());
req = req.clone({
setHeaders: {
Authorization: 'Bearer ' + this.oauthService.getAccessToken()
}
});
return next.handle(req);
另一种方式
使用 set 或 append 函数设置 HttpHeader
const reqHeader = new HttpHeaders().set('Authorization', 'Bearer ' + this.accessToken);
return this.http.get<any[]>(this.webApiUrlEndPoint, { headers: reqHeader});
我很困惑如何在 Angular 5 中为简单的 Get 请求创建一个好的 header。
这就是我需要在 Angular 中做的事情:
这是我目前所拥有的:
getUserList(): Observable<UserList[]> {
const headers = new Headers();
let tokenParse = JSON.parse(this.token)
headers.append('Authorization', `Bearer ${tokenParse}`);
const opts = new RequestOptions({ headers: headers });
console.log(JSON.stringify(opts));
const users = this.http.get<UserList[]>(this.mainUrl, opts)
return users
.catch(this.handleError.handleError);
}
这是我 console.log 中的回复:
{"method":null,"headers":{"Authorization":["Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImYwODZlM2FiYTk0ZjVhMjVmNDhiNzlkYmI2YWUwOWY4YzE2MTUyMzg2N2I5MDZiY2MzNWQyNWJiYTZmYTE4YjEwZjA1MjZiNThkZjE2Y2FjIn0.eyJhdWQiOiJmMDExY2M1OC00MGNlLTQzYTktOGY3MS04NDI0OTRlM2E5OTciLCJqdGkiOiJmMDg2ZTNhYmE5NGY1YTI1ZjQ4Yjc5ZGJiNmFlMDlmOGMxNjE1MjM4NjdiOTA2YmNjMzVkMjViYmE2ZmExOGIxMGYwNTI2YjU4ZGYxNmNhYyIsImlhdCI6MTUyMzU1MTQ0NSwibmJmIjoxNTIzNTUxNDQ1LCJleHAiOjE1MjM1NTQ0NDUsInN1YiI6IjIiLCJzY29wZXMiOlsiYXV0aGVudGljYXRlZCIsImFuZ3VkcnUiXX0.E-WdQTl7nPDW0gj0rohfql-QgnAinzvDxPR-pySMrG07XFY9tA6Ex7IL23pDBmKDmQO8RcZKa0L5r6SRQq9_iqzMWzn5Zxp94J9TJrpZ2KGMoLR_FbK_tpC5G5q5vUnCe3q34sH7cPdT_2cI704OWWaYmIUKKpXWUIG0PJw_uKSJ_uOifPv59RZGQkoaQ9gPywDKe-uamm1Faug-Kk2YnFMoEJq7ou19zyxgdpX80ZTPUae67uB0PGLRuvxfGaqVsJ8k0NunAY3-pyUnBwR_3eeuOxf4TyfW2aiOJ9kuPgsfV4Z1JD7nMpNtTHMJaXEyNkBW8RlYHD1pj4dkdnsDmw"]},"body":null,"url":null,"withCredentials":null,"responseType":null}
看起来很漂亮。但是给我这个错误
GET http://druang.dd:8080/user-list?_format=json 403 (Forbidden)
还有一条线索可以解开这个谜团。在 Sublime 文本中,如果我将鼠标放在 opts
上,它会显示如下内容:
ERROR in src/app/services/userlist.service.ts(33,59): error TS2345: Argument of type 'RequestOptions' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: Ht...'. Types of property 'headers' are incompatible. Type 'Headers' is not assignable to type 'HttpHeaders | { [header: string]: string | string[]; }'. Type 'Headers' is not assignable to type '{ [header: string]: string | string[]; }'. Index signature is missing in type 'Headers'.
有什么想法吗?? 这是完整的 Git repo 感谢您的帮助!
两件事:
headers.append(...)
不会改变 header 的 object,因此您的授权 header 不会被发送。你需要做headers = headers.append(...)
尝试
this.http.get<UserList[]>(this.mainUrl, { headers: headers });
我不是很擅长编程,但有一点尝试和失败 如果找到这个:
getUserList(): Observable<UserList[]> {
let tokenParse = JSON.parse(this.token)
// let myHeaders = new Headers();
// myHeaders.set('Authorization', `Bearer ${tokenParse}`);
// let options = new RequestOptions({ headers: myHeaders});
const users = this.http.get<UserList[]>(this.mainUrl, { headers:new HttpHeaders().append('Authorization', `Bearer ${tokenParse}`)})
// const users = this.http.get<UserList[]>(this.mainUrl, options);
return users
.catch(this.handleError.handleError);
}
我使用 .set
还是 .append
并不重要,归根结底,这两种情况都有效...
我真的不知道发生了什么,所以,如果有人想在评论中解释它,欢迎您...
我建议使用 HttpInterceptor
为传出请求设置默认 HTTP header,而不是向每个调用添加额外的 HTTP header。
HTTP Client - Setting default headers @ angular.io
在您的示例中,您可以执行以下操作:
import { Http, Headers, Response } from '@angular/http';
getLoggedInUser(auth_token): Observable<any> {
const headers = new Headers({
'Content-Type': 'application/json',
'Authorization': `Bearer ${auth_token}`
})
return this.http.get(apiUrl, { headers: headers })
}
对于 get
请求,我使用了以下代码并且有效
import { HttpClient, HttpHeaders } from '@angular/common/http';
getServerList(){
var reqHeader = new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + JSON.parse(localStorage.getItem('mpManagerToken'))
});
return this.http.get<Server[]>(`${environment.apiUrl}/api/Servers/GetServerList`, { headers: reqHeader });
}
在Angular6和7中,该方法可用于拦截所有HTTP请求并添加bearer token。
此处提供了实施教程。 Youtube,这个频道有所有的教程。
拦截器组件
import {
HttpInterceptor,
HttpRequest,
HttpHandler,
HttpUserEvent,
HttpEvent
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { UserService } from '../shared/user.service';
import { tap } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private router: Router) {}
intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
if (req.headers.get('No-Auth') === 'True') {
return next.handle(req.clone());
}
if (localStorage.getItem('userToken') != null) {
const clonedreq = req.clone({
headers: req.headers.set(
'Authorization',
'Bearer ' + localStorage.getItem('userToken')
)
});
return next.handle(clonedreq).pipe(
tap(
succ => {},
err => {
if (err.status === 401) {
// this.router.navigateByUrl('/login');
} else if ((err.status = 403)) {
// this.router.navigateByUrl('/forbidden');
// alert(err.localStorage.getItem('userToken'));
}
}
)
);
} else {
this.router.navigateByUrl('/login');
}
}
}
保护组件
import { Injectable } from '@angular/core';
import {
CanActivate,
ActivatedRouteSnapshot,
RouterStateSnapshot,
Router
} from '@angular/router';
import { Observable } from 'rxjs';
import { UserService } from '../shared/user.service';
import { ToastrService } from 'ngx-toastr';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(
private router: Router,
private userService: UserService,
private toastr: ToastrService
) {}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): boolean {
if (localStorage.getItem('userToken') != null) {
const roles = next.data['roles'] as Array<string>;
if (roles) {
const match = this.userService.roleMatch(roles);
if (match) {
return true;
} else {
// tslint:disable-next-line: quotemark
this.toastr.info("You don't have access to this page");
this.router.navigate(['/login']);
// this.router.navigate(['/forbidden']);
return false;
}
} else {
return true;
}
}
this.router.navigate(['/login']);
return false;
}
}
将其添加到 app.modules.ts
providers: [
ConfirmationDialogService,
UserService,
DoctorService,
{ provide: OwlDateTimeIntl, useClass: DefaultIntl },
{ provide: OWL_DATE_TIME_FORMATS, useValue: MY_MOMENT_FORMATS },
AuthGuard,
{
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi: true
}
],
然后把守卫加到route
{
path: 'adminPanel',
component: AdminPanelComponent,
canActivate: [AuthGuard],
data: { roles: ['Admin'] }
},
'Authorization': 'Bearer ' + access_token,
有效
虽然@HassanRahman 为 get
个请求显示它,但对于 post
个请求,
import { HttpClient, HttpHeaders } from '@angular/common/http';
getServerList(){
postData = { your data }
var reqHeader = new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + JSON.parse(localStorage.getItem('mpManagerToken'))
});
return this.http.post<Server[]>(`${environment.apiUrl}/api/Servers/GetServerList`, postData, { headers: reqHeader });
}
我已经使用了上述所有建议的格式来附加带有访问令牌的 headers,它在请求 header 中添加空值,如“Authorization Bearer null”。 如果我在 adding/cloning headers 行之前打印 accesstoken,accesstoken 值将打印在浏览器控制台中。这是我使用的格式。
console.log("Inside Interceptor accesstoken : " + this.oauthService.getAccessToken());
req = req.clone({
setHeaders: {
Authorization: 'Bearer ' + this.oauthService.getAccessToken()
}
});
return next.handle(req);
另一种方式 使用 set 或 append 函数设置 HttpHeader
const reqHeader = new HttpHeaders().set('Authorization', 'Bearer ' + this.accessToken);
return this.http.get<any[]>(this.webApiUrlEndPoint, { headers: reqHeader});