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 - 如何发送授权标头?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用授权标头发出 GET CORS 请求

使用 OPTIONS 方法未使用 http 请求 Angular 6 发送授权标头

如何在 POST 中发送 ClientId 和 ClientSecret,而不是在带有 ClientCredentialsAccessTokenProvider 的标头中发送

JWT:如何在标头中发送授权?

在 HTTP-Request 中使用 JWT 发送授权标头

如何在飞镖的 API POST 调用中传递授权标头?