Je dois définir des en-têtes d'autorisation après la connexion de l'utilisateur, pour chaque demande ultérieure.
Pour définir des en-têtes pour une demande particulière,
import {Headers} from 'angular2/http';
var headers = new Headers();
headers.append(headerName, value);
// HTTP POST using these headers
this.http.post(url, data, {
headers: headers
})
// do something with the response
Mais il ne serait pas possible de définir manuellement les en-têtes de demande pour chaque demande de cette manière.
Comment définir les en-têtes définis une fois que l'utilisateur s'est connecté et supprimer également ces en-têtes à la déconnexion?
Réponses:
Pour répondre, vous vous demandez si vous pourriez fournir un service qui enveloppe l'
Http
objet d' origine d'Angular. Quelque chose comme décrit ci-dessous.Et au lieu d'injecter l'
Http
objet, vous pouvez injecter celui-ci (HttpClient
).Je pense aussi que quelque chose pourrait être fait en utilisant plusieurs fournisseurs pour la
Http
classe en fournissant votre propre classe en étendant celle-Http
ci ... Voir ce lien: http://blog.oughttram.io/angular2/2015/11/23/multi-providers -en-angulaire-2.html .la source
Bearer ${token}
, / \ "/ g, '')]);Les intercepteurs HTTP sont désormais disponibles via le nouveau
HttpClient
depuis@angular/common/http
, à partir des versions Angular 4.3.x et au-delà .Il est assez simple d'ajouter un en-tête pour chaque demande maintenant:
Il y a un principe d'immuabilité , c'est la raison pour laquelle la demande doit être clonée avant de mettre quelque chose de nouveau dessus.
Comme l'édition des en-têtes est une tâche très courante, il existe en fait un raccourci pour cela (lors du clonage de la demande):
const clonedRequest = req.clone({ setHeaders: { Authorization: 'Bearer 123' } });
Après avoir créé l'intercepteur, vous devez l'enregistrer à l'aide de la
HTTP_INTERCEPTORS
fourniture.la source
L'extension
BaseRequestOptions
peut être très utile dans ce scénario. Découvrez le code suivant:Cela devrait inclure «My-Custom-Header» dans chaque appel.
Mettre à jour:
Pour pouvoir modifier l'en-tête à tout moment au lieu du code ci-dessus, vous pouvez également utiliser le code suivant pour ajouter un nouvel en-tête:
pour supprimer vous pouvez faire
Il existe également une autre fonction que vous pouvez utiliser pour définir la valeur:
La solution ci-dessus n'est toujours pas complètement valide dans un contexte dactylographié. _defaultHeaders est protégé et n'est pas censé être utilisé comme ça. Je recommanderais la solution ci-dessus pour une solution rapide, mais pour longtemps, il vaut mieux écrire votre propre wrapper autour des appels http qui gère également l'auth. Prenez l'exemple suivant de auth0 qui est meilleur et propre.
https://github.com/auth0/angular2-jwt/blob/master/angular2-jwt.ts
Mise à jour - juin 2018 Je vois beaucoup de gens opter pour cette solution mais je conseillerais le contraire. L'ajout d'en-tête au niveau mondial enverra un jeton d'authentification à chaque appel d'API sortant de votre application. Ainsi, les appels api allant à des plugins tiers comme intercom ou zendesk ou tout autre api porteront également votre en-tête d'autorisation. Cela pourrait entraîner un gros défaut de sécurité. Donc, à la place, utilisez l'intercepteur globalement mais vérifiez manuellement si l'appel sortant est vers le point de terminaison api de votre serveur ou non, puis attachez l'en-tête d'authentification.
la source
_defaultOptions
est protégé donc ne peut pas être appelé du serviceMême si je réponds très tard, cela pourrait aider quelqu'un d'autre. Pour injecter des en-têtes à toutes les requêtes quand il
@NgModule
est utilisé, on peut faire ce qui suit:(J'ai testé cela dans Angular 2.0.1)
Maintenant,
@NgModule
procédez comme suit:la source
CustomRequestOptions
même lors de l'utilisation de @ Inject / @ Injectable. La solution que j'ai réalisée était de prolongerRequestOptions
, nonBaseRequestOptions
. FournirBaseRequestOptions
ne fonctionnera pas, mais étendre à laRequestOptions
place fait fonctionner DI à nouveau.Authorization
tête n'est défini qu'une seule fois lors du lancement de l'application.Dans
Angular 2.1.2
j'ai approché cela en étendant le Http angulaire:puis dans mes fournisseurs d'applications, j'ai pu utiliser une usine personnalisée pour fournir «Http»
maintenant, je n'ai pas besoin de déclarer chaque méthode Http et
http
je peux l'utiliser normalement dans toute mon application.la source
request()
méthode que vous surchargez a deux signatures d'appel et laoptions
propriété est utilisée uniquement lorsqu'elle esturl
spécifiée en tant que chaîne. Dans le cas oùurl
est une instance deRequest
, laoptions
propriété est simplement ignorée. Cela pourrait entraîner des erreurs difficiles à détecter. Veuillez consulter ma réponse pour plus de détails.Créez une classe Http personnalisée en étendant le
Http
fournisseur Angular 2 et remplacez simplement la méthodeconstructor
etrequest
dans votre classe Http personnalisée. L'exemple ci-dessous ajoute un en-Authorization
tête dans chaque demande http.Configurez ensuite votre main
app.module.ts
pour fournir leXHRBackend
commeConnectionBackend
fournisseur et leRequestOptions
à votre classe Http personnalisée:Après cela, vous pouvez maintenant utiliser votre fournisseur http personnalisé dans vos services. Par exemple:
Voici un guide complet - http://adonespitogo.com/articles/angular-2-extending-http-provider/
la source
setRouter(router)
. Ou vous pouvez créer une autre classe et y injecter votre classe http personnalisée au lieu du contraire.Pour Angular 5 et supérieur, nous pouvons utiliser HttpInterceptor pour généraliser les opérations de demande et de réponse. Cela nous aide à éviter la duplication:
1) En-têtes communs
2) Spécification du type de réponse
3) Requête de requête
Nous pouvons utiliser cette classe AuthHttpInterceptor comme fournisseur pour les HttpInterceptors:
la source
Mieux vaut tard que jamais ... =)
Vous pouvez prendre le concept d'extension
BaseRequestOptions
(à partir d'ici https://angular.io/docs/ts/latest/guide/server-communication.html#!#override-default-request-options ) et actualiser les en-têtes "à la volée" "(pas seulement dans le constructeur). Vous pouvez utiliser le remplacement de la propriété geters / setter "headers" comme ceci:la source
C'est ainsi que je l'ai fait pour définir un jeton à chaque demande.
Et inscrivez-vous dans app.module.ts
la source
Voici une version améliorée de la réponse acceptée, mise à jour pour Angular2 final:
Bien sûr, il devrait être étendu pour des méthodes comme
delete
etput
si nécessaire (je n'en ai pas encore besoin à ce stade de mon projet).L'avantage est qu'il y a moins de code dupliqué dans les méthodes
get
/post
/ ....Notez que dans mon cas, j'utilise des cookies pour l'authentification. J'avais besoin de l'en-tête pour i18n (l'en-
Accept-Language
tête) car de nombreuses valeurs renvoyées par notre API sont traduites dans la langue de l'utilisateur. Dans mon application, le service i18n contient la langue actuellement sélectionnée par l'utilisateur.la source
Que diriez-vous de conserver un service distinct comme suit
et lorsque vous appelez cela depuis un autre endroit, utilisez
this.httpClientService.addHeader("Authorization", "Bearer " + this.tok);
et vous verrez l'en-tête ajouté, par exemple: - Autorisation comme suit
la source
Après quelques recherches, j'ai trouvé la finale et le moyen le plus simple est de prolonger
BaseRequestOptions
ce que je préfère.Voici les façons dont j'ai essayé d'abandonner pour une raison quelconque:
1. étendre
BaseRequestOptions
et ajouter des en-têtes dynamiquesconstructor()
. Cela ne peut pas fonctionner si je me connecte. Il sera créé une fois. Ce n'est donc pas dynamique.2. étendre
Http
. Même raison que ci-dessus, je ne peux pas ajouter d'en-têtes dynamiquesconstructor()
. Et si je réécris larequest(..)
méthode et que je définis des en-têtes, comme ceci:Vous avez juste besoin d'écraser cette méthode, mais pas toutes les méthodes get / post / put.
3.Et ma solution préférée est d'étendre
BaseRequestOptions
et d'écrasermerge()
:cette
merge()
fonction sera appelée pour chaque demande.la source
BaseRequestOptions
. Malheureusement, cela n'a pas fonctionné pour moi. des raisons possibles?AuthRequestOptions
au reste de l'application? J'ai essayé de mettre cela dans laproviders
section mais cela n'a rien fait.RequestOptions
, nonBaseRequestOptions
. angular.io/api/http/BaseRequestOptions{ provide: RequestOptions, useClass: AuthRequestOptions }
Bien que je réponde très tard, mais si quelqu'un cherche une solution plus simple.
Nous pouvons utiliser angular2-jwt. angular2-jwt est utile pour attacher automatiquement un jeton Web JSON (JWT) en tant qu'en-tête d'autorisation lors des requêtes HTTP à partir d'une application Angular 2.
Nous pouvons définir des en-têtes globaux avec une option de configuration avancée
Et l'envoi par jeton de demande comme
la source
J'aime l'idée de remplacer les options par défaut, cela semble être une bonne solution.
Cependant, si vous souhaitez étendre la
Http
classe. Assurez-vous de lire attentivement!Certaines réponses ici montrent en fait une surcharge incorrecte de
request()
méthode, ce qui pourrait entraîner des erreurs difficiles à détecter et un comportement étrange. Je suis tombé dessus moi-même.Cette solution est basée sur l'
request()
implémentation d'une méthode dans Angular4.2.x
, mais devrait être compatible avec l'avenir:Notez que j'importe la classe d'origine de cette façon
import { Http as NgHttp } from '@angular/http';
afin d'éviter les conflits de noms.Et voici l'exemple de la façon d'enregistrer cette classe substituée avec le conteneur DI:
Avec une telle approche, vous pouvez injecter la
Http
classe normalement, mais votre classe surchargée sera injectée comme par magie. Cela vous permet d'intégrer facilement votre solution sans changer d'autres parties de l'application (polymorphisme en action).Ajoutez simplement
httpProvider
à laproviders
propriété de vos métadonnées de module.la source
Le plus simple de tous
Créer un
config.ts
fichierEnsuite
service
, importez simplement leconfig.ts
fichierJe pense que c'était le plus simple et le plus sûr.
la source
Il y a eu quelques changements pour angular 2.0.1 et supérieur:
la source
J'ai pu choisir une solution plus simple> Ajouter un nouvel en-tête aux options par défaut fusionner ou charger par votre fonction get (ou autre) api.
Bien sûr, vous pouvez externaliser ces en-têtes dans les options par défaut ou quoi que ce soit dans votre classe. C'est dans l'API de classe d'exportation api.ts @Injectable () générée par Ionic {}
C'est très rapide et ça marche pour moi. Je ne voulais pas du format json / ld.
la source
Vous pouvez utiliser
canActive
dans vos itinéraires, comme ceci:Tiré de: https://auth0.com/blog/angular-2-authentication
la source