【问题标题】:http post - how to send Authorization header?http post - 如何发送授权标头?
【发布时间】: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

【问题讨论】:

标签: rest http authentication angular typescript


【解决方案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://stackoverflow.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

        【讨论】:

          猜你喜欢
          • 2016-03-26
          • 1970-01-01
          • 1970-01-01
          • 2016-07-12
          • 2020-10-23
          • 2017-10-29
          • 2015-04-25
          • 2020-05-22
          • 1970-01-01
          相关资源
          最近更新 更多