如何将授权标头添加到 Angular http 请求?
Posted
技术标签:
【中文标题】如何将授权标头添加到 Angular http 请求?【英文标题】:How to add Authorization Header to Angular http request? 【发布时间】:2018-05-04 04:45:46 【问题描述】:这是我的第一篇文章。
我刚刚开始学习 Go 和 Angular,我正在尝试将 Angular 应用程序连接到 Go api。我已经写了两个,并且一直在确定问题的根源。我认为这是一个 CORS 问题,但如果我不在我的 Angular http 请求中包含标头代码行,它就可以正常工作。在这一点上,我只是想添加标题。授权码尚未实现。
这两个应用都在本地运行,Go 应用在端口 5000 上,Angular 在 4200 上
Angular http 请求不起作用:
this.http.get<ProjectedBalance>(requestUrl, headers: new HttpHeaders().set('Authorization', 'my-auth-token'))
.subscribe(data =>
this.projBalance = data.projBalance;
有效的 Angular http 请求:
this.http.get<ProjectedBalance>(requestUrl)
.subscribe(data =>
this.projBalance = data.projBalance;
我收到此错误:
对预检请求的响应未通过访问控制检查:否 请求中存在“Access-Control-Allow-Origin”标头 资源。因此不允许使用原点“http://localhost:4200” 使用权。响应的 HTTP 状态代码为 403
我在我的 go 代码中使用了 gorilla/mux 和 gorilla/handlers
router := mux.NewRouter()
router.HandleFunc("/home/endDate", GetProjBalance).Methods("GET", "OPTIONS")
headersOk := handlers.AllowedHeaders([]string"X-Requested-With, Content-Type, Authorization")
originsOk := handlers.AllowedOrigins([]string"*")
methodsOk := handlers.AllowedMethods([]string"GET", "HEAD", "POST", "PUT", "OPTIONS")
//start server on port
log.Fatal(http.ListenAndServe(":5000", handlers.CORS(originsOk, headersOk, methodsOk)(router)))
Chrome 开发工具的标头
Request URL:http://localhost:5000/home/2020-12-21
Request Method:OPTIONS
Status Code:403 Forbidden
Remote Address:[::1]:5000
Referrer Policy:no-referrer-when-downgrade
Response Headers
view source
Content-Length:0
Content-Type:text/plain; charset=utf-8
Date:Mon, 20 Nov 2017 21:39:43 GMT
Request Headers
view source
Accept:*/*
Accept-Encoding:gzip, deflate, br
Accept-Language:en-US,en;q=0.9,uz;q=0.8
Access-Control-Request-Headers:authorization
Access-Control-Request-Method:GET
Connection:keep-alive
Host:localhost:5000
Origin:http://localhost:4200
【问题讨论】:
考虑以问题的形式重新表述您的帖子... 我不确定为什么handlers.CORS
不起作用,但如果您不使用 CORS,则需要将您的开发请求代理到端口 5000。在生产中,您将运行在端口 80 上所以没有冲突,但是由于您使用 angular 的开发服务器并在本地运行您的 go 服务器,localhost:4200
和localhost:5000
是不同的来源。我不确定执行此操作的“角度 5 方式”是什么,但 webpack-dev-server
在 package.json
中有一个超简单的 proxy
字段,您基本上想复制它。
您好 gobuckeyes,您能否向我提供您的客户端在其向 API 的请求中发送的标头列表(来自开发工具中的网络选项卡)。如果将所有 3 个 CORS 设置为 "*"
,问题是否仍然存在?
@Mihailo 我发布了来自开发工具的标题。将所有三个 CORS 更改为 "*" 将错误更改为 405 - Method not allowed。谢谢
尝试将AllowedMethods()
变回原来的样子。您的客户端应该发送 2 个请求,一个具有 OPTIONS
方法,另一个应该是 GET
(针对此特定请求)。还原 AllowedMethods
后,尝试再次发送请求,如果错误仍然存在,请使用来自 GET
请求的数据更新问题。
【参考方案1】:
以下示例适合您只希望在访问需要授权的资源时添加一些标头的情况,请参见下面的代码。请注意,您需要在 authentication.service.ts 中创建 getToken 方法。
import Injectable from '@angular/core';
import
HttpInterceptor,
HttpRequest,
HttpHandler,
HttpEvent
from '@angular/common/http';
import Observable from 'rxjs';
import environment from '../../environments/environment';
import AuthenticationService from '../services/authentication.service';
@Injectable(
providedIn: 'root'
)
export class AuthenticationInterceptorService implements HttpInterceptor
constructor(public authenticationService: AuthenticationService)
intercept(
request: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>>
const accessToken: string = this.authenticationService.getToken();
// set global application headers.
request = request.clone(
setHeaders:
'Content-Type': 'application/json; charset=utf-8',
Accept: 'application/json',
'X-AppName': environment.xAppName,
'X-Locale': 'en'
);
// Set headers for requests that require authorization.
if (accessToken)
const authenticatedRequest = request.clone(
headers: request.headers.set(
'Authorization',
`Token token=$accessToken`
)
);
// Request with authorization headers
return next.handle(authenticatedRequest);
else
// Request without authorization header
return next.handle(request);
在app.module.ts中注册拦截器,如下图:
import BrowserModule from '@angular/platform-browser';
import NgModule from '@angular/core';
import AuthenticationInterceptorService from './services/authentication-interceptor.service';
import AppRoutingModule from './app-routing.module';
import AppComponent from './app.component';
import HttpClientModule, HTTP_INTERCEPTORS from '@angular/common/http';
@NgModule(
declarations: [AppComponent],
imports: [BrowserModule, AppRoutingModule, HttpClientModule],
providers: [
provide: HTTP_INTERCEPTORS,
useClass: AuthenticationInterceptorService,
multi: true
],
bootstrap: [AppComponent]
)
export class AppModule
【讨论】:
【参考方案2】:Angular 6 ==> 带有授权标头的 HTTP Get 请求示例
public IsClientCreditCardExits(companyId: string, token: any)
let header = new Headers( 'Authorization': `Bearer $token` );
const options = new RequestOptions(
headers: header,
);
return this._http.get(this.ApiURL + "api/Subscriptions/IsClientCreditCardExits/" + companyId + "/", options);
【讨论】:
【参考方案3】:如果您不想添加拦截器,这对我有用:
var header =
headers: new HttpHeaders()
.set('Authorization', `Basic $btoa(AuthService.getToken())`)
this.http.get(url, header)
对于承载,
set('Authorization', `Bearer $AuthService.getToken()`)
【讨论】:
【参考方案4】:关于在 Angular > 4 中处理身份验证标头的最佳方式,最好使用Http Interceptors
将它们添加到每个请求中,然后使用Guards
进行保护你的路线。
这是我在应用中使用的AuthInterceptor
的完整示例:
auth.interceptor.ts
import HttpEvent, HttpHandler, HttpInterceptor, HttpRequest from '@angular/common/http';
import Injectable from '@angular/core';
import Observable from 'rxjs/Observable';
import AuthService from './auth.service';
@Injectable()
export class AuthInterceptor implements HttpInterceptor
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>
req = req.clone(
setHeaders:
'Content-Type' : 'application/json; charset=utf-8',
'Accept' : 'application/json',
'Authorization': `Bearer $AuthService.getToken()`,
,
);
return next.handle(req);
您需要在app.module
中将您的拦截器注册为提供者:
app.module.ts
import HTTP_INTERCEPTORS, HttpClientModule from '@angular/common/http';
import AuthInterceptor from '../auth/auth.interceptor';
...
imports: [
HttpClientModule,
...
],
providers: [
provide : HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi : true,
,
...
],
...
您可以在post 中进一步了解此方法。
关于 Go 方面,这很可能是您发送的请求标头与标头不匹配的情况CORS 允许。 您应该尝试的第一件事是允许所有这些:
headersOk := handlers.AllowedHeaders([]string"*")
originsOk := handlers.AllowedOrigins([]string"*")
methodsOk := handlers.AllowedMethods([]string"GET", "HEAD", "POST", "PUT", "OPTIONS")
如果问题消失,请尝试将您的 CORS 与您的客户发送的内容一一对应。
【讨论】:
这适用于在 Angular 应用程序中添加标题。谢谢!对于 Go 部分,我能够使用这种方法。 ***.com/questions/22452804/… 整洁!很高兴我能帮上忙 :) 祝你好运!【参考方案5】:这是一个例子:
this.http
.get(url, return new RequestOptions(
headers: new Headers(
Authorization: `Bearer $authtoken`
),
))
.map(res => res.json());
【讨论】:
以上是关于如何将授权标头添加到 Angular http 请求?的主要内容,如果未能解决你的问题,请参考以下文章
了解 JWT 和 HTTP 授权标头? (客户端:Angular,服务器:php)