Угловой HttpInterceptor Messing с Github API Call - PullRequest
1 голос
/ 14 мая 2019

В настоящее время я внедряю систему аутентификации, в которой пользователь входит в систему и получает токен JWT с сервера, который хранится в localStorage. Я также написал собственный HttpInterceptor, который присоединяет токен пользователя к исходящим HTTP-запросам. Это хорошо работает для локальных конечных точек, однако у меня также есть запрос GET, извлекающий аватар каждого пользователя из API GitHub, и он больше не работает из-за перехватчика. Я получаю ошибку аутентификации 401 от GitHub.

Вот код от HttpInterceptor:

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    const idToken = localStorage.getItem("access_token");

    if (idToken && req.url.includes("localhost")) {
      const cloned = req.clone({
        headers: req.headers.set("Authorization", `Bearer ${idToken}`)
      });
      return next.handle(cloned);
    } else {
      return next.handle(req);
    }
  }
}

Вот заголовки запросов, которые отправляются на GitHub:

Accept: application/json, text/plain, */*
Authorization: token ... (removed for privacy)
Content-Type: application/json
Origin: http://localhost:4200
Referer: http://localhost:4200/contacts
User-Agent: ...(removed for privacy)

Вот ответ от GitHub API:

Request URL: https://api.github.com/users/...
Request Method: GET
Status Code: 401 Unauthorized
Remote Address: 192.30.253.117:443
Referrer Policy: no-referrer-when-downgrade

А вот код службы, которая выбирает аватар GitHub:

const githubOptions = {
  headers: new HttpHeaders({
    "Content-Type": "application/json",
    Authorization: "token ..." // removed for privacy
  })
};

@Injectable({
  providedIn: "root"
})
export class ContactServiceService {
  constructor(private http: HttpClient) {}

  ...

  getGithub(user: string): Promise<any> {
    return this.http
      .get<any>(`https://api.github.com/users/${user}`, githubOptions)
      .toPromise();
  }
}

Странно то, что если дважды щелкнуть HTTP-запрос в консоли Chrome Network, он пройдет нормально и вернет желаемый ответ. Но по какой-то причине HttpInterceptor не позволяет ему пройти в моем коде.

Любая помощь очень ценится!

1 Ответ

1 голос
/ 14 мая 2019

Это потому, что заголовок авторизации вашего приложения переопределяет заголовок для github. На самом деле вы пытаетесь избежать этого, проверяя URL с помощью этого оператора if if (idToken && req.url.includes("localhost")) {

Однако, похоже, ваш вызов req.headers.set переопределяет заголовок авторизации и для других запросов. Попробуйте установить заголовок так:

const cloned = request.clone({
  setHeaders: {
    Authorization: `Bearer ${idToken}`
  }
});
...