http post - 如何发送授权标头?
Posted
技术标签:
【中文标题】http post - 如何发送授权标头?【英文标题】:http post - how to send Authorization header? 【发布时间】:2017-01-17 10:01:54 【问题描述】:如何在 Angular2 RC6 中为 http 请求添加标头? 我得到以下代码:
login(login: String, password: String): Observable<boolean>
console.log(login);
console.log(password);
this.cookieService.removeAll();
let headers = new Headers();
headers.append("Authorization","Basic YW5ndWxhci13YXJlaG91c2Utc2VydmljZXM6MTIzNDU2");
this.http.post(AUTHENTICATION_ENDPOINT + "?grant_type=password&scope=trust&username=" + login + "&password=" + password, null, headers: headers).subscribe(response =>
console.log(response);
);
//some return
问题是,角度不添加授权标头。取而代之的是,在请求中,我可以看到以下附加标头:
Access-Control-Request-Headers:authorization
Access-Control-Request-Method:POST
并在 Accept-Encoding 中添加了 sdch:
Accept-Encoding:gzip, deflate, sdch
不幸的是,没有授权标头。如何正确添加?
我的代码发送的整个请求如下所示:
OPTIONS /oauth/token?grant_type=password&scope=trust&username=asdf&password=asdf HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Access-Control-Request-Method: POST
Origin: http://localhost:3002
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/52.0.2743.116 Safari/537.36
Access-Control-Request-Headers: authorization
Accept: */*
Referer: http://localhost:3002/login
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,pl;q=0.6
【问题讨论】:
您是否尝试过提供自己的请求选项? ***.com/a/35047978/4102561 @Supamiu 不幸的是,这个解决方案不起作用。我试过: this.http._defaultOptions.headers.set('Authorization', 'Basic YW5ndWxhci13YXJlaG91c2Utc2VydmljZXM6MTIzNDU2');并得到相同的结果 您在问题中显示的请求是OPTIONS
preflight 请求,您能否添加 POST 请求?(应该在您的网络选项卡中此请求之后)
复制:***.com/questions/38368794/…
Angular 2 Basic Authentication not working的可能重复
【参考方案1】:
好的。我发现了问题。
它不在 Angular 方面。老实说,完全没有问题。
我无法成功执行请求的原因是我的服务器应用没有正确处理 OPTIONS 请求。
为什么选择 OPTIONS,而不是 POST?我的服务器应用程序位于不同的主机上,然后是前端。由于 CORS,我的浏览器将 POST 转换为 OPTION: http://restlet.com/blog/2015/12/15/understanding-and-using-cors/
在这个答案的帮助下: Standalone Spring OAuth2 JWT Authorization Server + CORS
我在我的服务器端应用程序上实施了适当的过滤器。
感谢@Supamiu - 指点我说我根本不发送 POST 的人。
【讨论】:
它发送OPTIONS
作为预检请求,然后发送POST
,如果一切顺利的话。它不会用OPTIONS
替换POST
。【参考方案2】:
你需要 RequestOptions
let headers = new Headers('Content-Type': 'application/json');
headers.append('Authorization','Bearer ')
let options = new RequestOptions(headers: headers);
return this.http.post(APIname,body,options)
.map(this.extractData)
.catch(this.handleError);
更多信息请查看link
【讨论】:
【参考方案3】:我相信您需要在订阅之前映射结果。你可以这样配置:
updateProfileInformation(user: User)
var headers = new Headers();
headers.append('Content-Type', this.constants.jsonContentType);
var t = localStorage.getItem("accessToken");
headers.append("Authorization", "Bearer " + t;
var body = JSON.stringify(user);
return this.http.post(this.constants.userUrl + "UpdateUser", body, headers: headers )
.map((response: Response) =>
var result = response.json();
return result;
)
.catch(this.handleError)
.subscribe(
status => this.statusMessage = status,
error => this.errorMessage = error,
() => this.completeUpdateUser()
);
【讨论】:
问题的重点不是如何处理http response,而是如何在request中添加合适的header。我确定我检查了您的建议 - 它不起作用,发送的标头仍然相同。 你得到了什么版本的角度? 我正在使用 Angular RC6 你对http请求做了一些额外的配置吗? headers.append("Authorization", "Bearer" + t; 这一行缺少右括号。【参考方案4】:如果你像我一样,盯着你的 angular/ionic 打字稿,看起来像..
getPdf(endpoint: string): Observable<Blob>
let url = this.url + '/' + endpoint;
let token = this.msal.accessToken;
console.log(token);
return this.http.post<Blob>(url,
headers: new HttpHeaders(
'Access-Control-Allow-Origin': 'https://localhost:5100',
'Access-Control-Allow-Methods': 'POST',
'Content-Type': 'application/pdf',
'Authorization': 'Bearer ' + token,
'Accept': '*/*',
),
//responseType: ResponseContentType.Blob,
);
当您设置选项但似乎无法弄清楚为什么它们不在任何地方..
好吧.. 如果你像我一样从get
的复制/粘贴开始这个post
,那么...
改为:
getPdf(endpoint: string): Observable<Blob>
let url = this.url + '/' + endpoint;
let token = this.msal.accessToken;
console.log(token);
return this.http.post<Blob>(url, null, // <----- notice the null *****
headers: new HttpHeaders(
'Authorization': 'Bearer ' + token,
'Accept': '*/*',
),
//responseType: ResponseContentType.Blob,
);
【讨论】:
Access-Control
标头由服务器设置,而不是客户端设置为Content-Type
【参考方案5】:
我有同样的问题。这是我使用 Angular 文档和 firebase Token 的解决方案:
getService()
const accessToken=this.afAuth.auth.currentUser.getToken().then(res=>
const httpOptions =
headers: new HttpHeaders(
'Content-Type': 'application/json',
'Authorization': res
)
;
return this.http.get('Url',httpOptions)
.subscribe(res => console.log(res));
);
【讨论】:
【参考方案6】:以下是问题的详细答案:
从 Angular 端将数据传递到 HTTP 标头(请注意,我是 在应用程序中使用 Angular4.0+)。
我们可以将数据传递到标头中的方法不止一种。 语法不同,但意思都一样。
// Option 1
const httpOptions =
headers: new HttpHeaders(
'Authorization': 'my-auth-token',
'ID': emp.UserID,
)
;
// Option 2
let httpHeaders = new HttpHeaders();
httpHeaders = httpHeaders.append('Authorization', 'my-auth-token');
httpHeaders = httpHeaders.append('ID', '001');
httpHeaders.set('Content-Type', 'application/json');
let options = headers:httpHeaders;
// Option 1
return this.http.post(this.url + 'testMethod', body,httpOptions)
// Option 2
return this.http.post(this.url + 'testMethod', body,options)
在调用中,您可以找到作为标题传递的字段,如下图所示:
不过,如果您遇到类似的问题......(您可能需要更改后端/WebAPI 端)
对预检请求的响应未通过访问控制检查:否 ''Access-Control-Allow-Origin'' 标头出现在请求的资源上。因此不允许使用原点 ''http://localhost:4200'' 访问
预检响应没有 HTTP ok 状态。
在https://***.com/a/52620468/3454221找到我的详细答案
【讨论】:
【参考方案7】:如果您是 ruby on rails 开发人员并且遇到类似问题,这是因为您的后端配置:尤其是在 api 模式下 所以与 已安装 gem 'rack-cors'
转到 app/config/cors.rb
修改此文件时请务必重新启动服务器。
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins 'domain_name:port or just use *'
resource '*',
headers: :any,
methods: [:get, :post, :put, :patch, :delete, :options, :head],
credentials: true
end
end
*credentials:true 行可以解决问题 然后在你的 SessionController 用户有效登录后 插入一行(假设您使用的是 gem 'jwt')
token = user.generate_jwt
response.headers['Authorization'] = token
generate_jwt 是模型 User 中调用的方法,它是
JWT.encode(id, key, alogrithm)
如果你使用 django,那已经为你处理好了 你只需要使用 已安装的应用:restframework_simplejwt
【讨论】:
以上是关于http post - 如何发送授权标头?的主要内容,如果未能解决你的问题,请参考以下文章
使用 OPTIONS 方法未使用 http 请求 Angular 6 发送授权标头
如何在 POST 中发送 ClientId 和 ClientSecret,而不是在带有 ClientCredentialsAccessTokenProvider 的标头中发送