【问题标题】:HttpClient's authorization headers returning null, tried all method from research but both of them not workingHttpClient 的授权标头返回 null,尝试了研究中的所有方法,但它们都不起作用
【发布时间】:2019-05-06 10:13:47
【问题描述】:

我有一个本教程提供的假后端服务,但是本教程的 Angular 版本已经很老了。我决定使用新版本的 angular 和 auth0/jwt,但这与教程所教的完全不同。即使我在 app.module 中有 JwtModule.forRoot,我也无法解决授权标头返回 null 的问题

我尝试做 console.log(connection.request.headers.get('Authorization')); 但它返回 null

这是我的代码: order.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable()
export class OrderService {

  constructor(private http: HttpClient) {
  }

  getOrders() {
    return this.http.get('/api/orders');
  }
}

fake-backend.ts

import { Http, BaseRequestOptions, Response, ResponseOptions, RequestMethod } from '@angular/http';
import { MockBackend, MockConnection } from '@angular/http/testing';
import { HttpClient } from '@angular/common/http';

export function fakeBackendFactory(
    backend: MockBackend, 
    options: BaseRequestOptions) {

  let token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ik1vc2ggSGFtZWRhbmkiLCJhZG1pbiI6dHJ1ZSwiZXhwIjoxMTExMTExMTExMX0.MkMCCNb5PMF-vdgpJTH0ZxFXeSPn0lJGyNBWkIJDzqE';

  backend.connections.subscribe((connection: MockConnection) => {
    // We are using the setTimeout() function to simulate an 
    // asynchronous call to the server that takes 1 second. 
    setTimeout(() => {
 // 
       // Fake implementation of /api/orders
       //
       if (connection.request.url.endsWith('/api/orders') && 
           connection.request.method === RequestMethod.Get) {
         if (connection.request.headers.get('Authorization') === 'Bearer ' + token) {
            connection.mockRespond(new Response(
              new ResponseOptions({ status: 200, body: [1, 2, 3] })
          ));
          } else {
           connection.mockRespond(new Response(
             new ResponseOptions({ status: 401 })
           ));
          }
        }



    }, 1000);
  });

  return new Http(backend, options);
}

export let fakeBackendProvider = {
    provide: HttpClient,
    useFactory: fakeBackendFactory,
    deps: [MockBackend, BaseRequestOptions]
};

app.module.ts

import { OrderService } from './services/order.service';
import { MockBackend } from '@angular/http/testing';
import { fakeBackendProvider } from './helpers/fake-backend';
import { AuthService } from './services/auth.service';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule, Http, BaseRequestOptions } from '@angular/http';
import { JwtModule, JWT_OPTIONS } from '@auth0/angular-jwt';
import { HttpClientModule, HttpClient } from '@angular/common/http';
import { RouterModule } from '@angular/router'; 

import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { LoginComponent } from './login/login.component';
import { SignupComponent } from './signup/signup.component';
import { AdminComponent } from './admin/admin.component';
import { NotFoundComponent } from './not-found/not-found.component';
import { NoAccessComponent } from './no-access/no-access.component';
import { AuthGuard } from './services/auth-guard.service';
import { AdminAuthGuard } from './services/admin-auth-guard.service';

export function tokenGetter(){
  return localStorage.getItem('token');
}

@NgModule({
  declarations: [
    AppComponent,
    LoginComponent,
    SignupComponent,
    AdminComponent,
    HomeComponent,
    NotFoundComponent,
    NoAccessComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    HttpClientModule,
    RouterModule.forRoot([
      { path: '', component: HomeComponent },
      {
        path: 'admin',
        component: AdminComponent, 
        canActivate: [AuthGuard, AdminAuthGuard]
      },
      { path: 'login', component: LoginComponent },
      { path: 'no-access', component: NoAccessComponent }
    ]),
    JwtModule.forRoot({
      config: { tokenGetter,
      whitelistedDomains: ['http://localhost:4200'],
      blacklistedRoutes: [],
      headerName: 'Authorization',
      throwNoTokenError: true,
      skipWhenExpired: false,
      authScheme: 'Bearer '
      }
    })
  ],
  providers: [
    OrderService,

    AuthService,
    AuthGuard,
    AdminAuthGuard,

    // For creating a mock back-end. You don't need these in a real app. 
    fakeBackendProvider,
    MockBackend,
    BaseRequestOptions,
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

admin.component.ts

import { OrderService } from './../services/order.service';
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-admin',
  templateUrl: './admin.component.html',
  styleUrls: ['./admin.component.css']
})
export class AdminComponent implements OnInit {
  orders: any[];

  constructor(private orderService: OrderService) { }

  ngOnInit() {
    this.orderService.getOrders()
      .subscribe(orders => this.orders = <any[]>orders);
  }
}

connection.request.headers.get('Authorization') 实际上返回 null,那么我怎样才能真正将授权标头更改为 'Bearer ' + token ?我已经为此工作了 2 天.....它仍然没有解决我只想实现类似 AuthHttp 的东西

【问题讨论】:

    标签: angular typescript httpclient authhttp


    【解决方案1】:

    我认为您应该像这样在服务中设置标头

    getOrders() {
     const httpOptions = {
      headers: new HttpHeaders({
        'Content-Type':  'application/json',
        'Authorization': 'my-auth-token'
      })
    };
    
     return this.http.get('/api/orders', httpOptions);
    }
    

    【讨论】:

    • 但这要长得多,如果使用 AuthHttp 我什至可以在 getOrders() 函数中写 return this.http.get('/api/orders', httpOptions); 然后其他事情会自动完成
    • 这是 Angular 团队建议的最佳实践。为了防止每次重写标头,我建议您使用 Authorization 标头创建通用 http 服务以在任何地方使用
    • ...但是还是不行,还是没有通过授权部分
    • @gamesymbol 你必须使用 HttpClientModule 而不是 HttpClient
    • 为什么在你的模块中使用 HttpClientModule 和 HttpClient ?仅导入 HttpClientModule
    猜你喜欢
    • 1970-01-01
    • 2015-01-27
    • 1970-01-01
    • 2016-10-20
    • 1970-01-01
    • 2016-02-11
    • 2023-03-13
    • 1970-01-01
    • 2019-06-22
    相关资源
    最近更新 更多