Necesito configurar algunos encabezados de autorización después de que el usuario haya iniciado sesión, para cada solicitud posterior.
Para configurar encabezados para una solicitud particular,
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
Pero no sería factible configurar manualmente encabezados de solicitud para cada solicitud de esta manera.
¿Cómo configuro los encabezados una vez que el usuario ha iniciado sesión y también elimino esos encabezados al cerrar sesión?
Respuestas:
Para responder, pregunta si podría proporcionar un servicio que envuelva el
Http
objeto original de Angular. Algo como se describe a continuación.Y en lugar de inyectar el
Http
objeto, podría inyectar este (HttpClient
).También creo que se podría hacer algo usando múltiples proveedores para la
Http
clase al proporcionar su propia clase extendiendo laHttp
... Vea este enlace: http://blog.thoughtram.io/angular2/2015/11/23/multi-providers -in-angular-2.html .fuente
Bearer ${token}
, / \ "/ g, '')]);Interceptores HTTP están ahora disponibles a través de la nueva
HttpClient
de@angular/common/http
, a partir de las versiones 4.3.x angular y más allá .Es bastante simple agregar un encabezado para cada solicitud ahora:
Existe un principio de inmutabilidad , esa es la razón por la que la solicitud debe clonarse antes de configurar algo nuevo en ella.
Como editar encabezados es una tarea muy común, en realidad hay un atajo para ello (al clonar la solicitud):
const clonedRequest = req.clone({ setHeaders: { Authorization: 'Bearer 123' } });
Después de crear el interceptor, debe registrarlo usando el
HTTP_INTERCEPTORS
provide.fuente
La extensión
BaseRequestOptions
podría ser de gran ayuda en este escenario. Mira el siguiente código:Esto debería incluir 'Mi encabezado personalizado' en cada llamada.
Actualizar:
Para poder cambiar el encabezado en cualquier momento que desee en lugar del código anterior, también puede usar el siguiente código para agregar un nuevo encabezado:
para eliminar puedes hacer
También hay otra función que puede usar para establecer el valor:
La solución anterior todavía no es completamente válida en el contexto mecanografiado. _defaultHeaders está protegido y no se debe usar de esta manera. Recomendaría la solución anterior para una solución rápida, pero a largo plazo es mejor escribir su propio contenedor alrededor de las llamadas http que también maneja la autenticación. Tome el siguiente ejemplo de auth0 que es mejor y limpio.
https://github.com/auth0/angular2-jwt/blob/master/angular2-jwt.ts
Actualización: junio de 2018 , veo que muchas personas optan por esta solución, pero aconsejaría lo contrario. Al agregar un encabezado global, se enviará un token de autenticación a cada llamada a la API que salga de su aplicación. Por lo tanto, las llamadas de la API que se dirigen a complementos de terceros como Intercom o Zendesk o cualquier otra API también llevarán su encabezado de autorización. Esto podría resultar en una gran falla de seguridad. Por lo tanto, use el interceptor globalmente, pero verifique manualmente si la llamada saliente se dirige hacia el punto final de la API de su servidor o no y luego adjunte el encabezado de autenticación.
fuente
_defaultOptions
está protegido, así que no se puede llamar desde el servicioAunque estoy respondiendo muy tarde, podría ayudar a alguien más. Para inyectar encabezados a todas las solicitudes cuando
@NgModule
se usa, se puede hacer lo siguiente:(Probé esto en Angular 2.0.1)
Ahora
@NgModule
haga lo siguiente:fuente
CustomRequestOptions
incluso cuando usaba @ Inject / @ Injectable. La solución que me di cuenta fue extenderRequestOptions
, noBaseRequestOptions
. ProporcionarBaseRequestOptions
no funcionará, pero extenderloRequestOptions
hace que DI vuelva a funcionar.Authorization
encabezado se configura solo una vez en el inicio de la aplicación.En
Angular 2.1.2
me acerqué a esto extendiendo el Http angular:luego en mis proveedores de aplicaciones pude usar una fábrica personalizada para proporcionar 'Http'
ahora no necesito declarar todos los métodos Http y puedo usarlos
http
normalmente en toda mi aplicación.fuente
request()
método, que está sobrecargando, tiene dos firmas de llamada y laoptions
propiedad se usa solo cuando seurl
especifica como cadena. En caso de queurl
sea una instancia deRequest
, laoptions
propiedad simplemente se ignora. Esto podría conducir a errores difíciles de detectar. Por favor vea mi respuesta para más detalles.Cree una clase Http personalizada extendiendo el
Http
proveedor Angular 2 y simplemente anule el métodoconstructor
yrequest
en su clase Http personalizada. El siguiente ejemplo agregaAuthorization
encabezado en cada solicitud http.Luego configure su main
app.module.ts
para proporcionar elXHRBackend
como elConnectionBackend
proveedor y elRequestOptions
a su clase Http personalizada:Después de eso, ahora puede usar su proveedor http personalizado en sus servicios. Por ejemplo:
Aquí hay una guía completa: http://adonespitogo.com/articles/angular-2-extending-http-provider/
fuente
setRouter(router)
. O puede crear otra clase e inyectar su clase http personalizada allí en lugar de lo contrario.Para Angular 5 y superior, podemos usar HttpInterceptor para generalizar las operaciones de solicitud y respuesta. Esto nos ayuda a evitar duplicar:
1) encabezados comunes
2) Especificando el tipo de respuesta
3) Solicitud de consulta
Podemos usar esta clase AuthHttpInterceptor como proveedor de los HttpInterceptors:
fuente
Más vale tarde que nunca ... =)
Puede tomar el concepto de extendido
BaseRequestOptions
(desde aquí https://angular.io/docs/ts/latest/guide/server-communication.html#!#override-default-request-options ) y actualizar los encabezados "sobre la marcha "(no solo en constructor). Puede usar la anulación de la propiedad "encabezados" getter / setter de esta manera:fuente
Así es como lo hice para configurar el token con cada solicitud.
Y regístrese en app.module.ts
fuente
Aquí hay una versión mejorada de la respuesta aceptada, actualizada para Angular2 final:
Por supuesto, debe extenderse para métodos como
delete
yput
si es necesario (todavía no los necesito en este momento en mi proyecto).La ventaja es que hay menos código duplicado en los métodos
get
/post
/ ...Tenga en cuenta que en mi caso uso cookies para la autenticación. Necesitaba el encabezado para i18n (el
Accept-Language
encabezado) porque muchos valores devueltos por nuestra API están traducidos al idioma del usuario. En mi aplicación, el servicio i18n contiene el idioma seleccionado actualmente por el usuario.fuente
¿Qué tal mantener un servicio separado como sigue?
y cuando llamas a esto desde otro lugar usa
this.httpClientService.addHeader("Authorization", "Bearer " + this.tok);
y verá el encabezado agregado, por ejemplo: - Autorización de la siguiente manera
fuente
Después de un poco de investigación, encontré la última y la forma más fácil es extender
BaseRequestOptions
lo que prefiero.Las siguientes son las formas en que intenté y me di por vencido por alguna razón:
1. extender
BaseRequestOptions
y agregar encabezados dinámicosconstructor()
. No puede funcionar si inicio sesión. Será creado una vez. Entonces no es dinámico.2. extender
Http
. La misma razón que la anterior, no puedo agregar encabezados dinámicosconstructor()
. Y si reescribo elrequest(..)
método y establezco encabezados, así:Solo necesita sobrescribir este método, pero no todos los métodos get / post / put.
3.Y mi solución preferida es extender
BaseRequestOptions
y sobrescribirmerge()
:merge()
Se llamará a esta función para cada solicitud.fuente
BaseRequestOptions
. Sin embargo, lamentablemente, esto no funcionó para mí. alguna razón posible?AuthRequestOptions
con el resto de la aplicación? Traté de poner esto en laproviders
sección pero no hizo nada.RequestOptions
, noBaseRequestOptions
. angular.io/api/http/BaseRequestOptions{ provide: RequestOptions, useClass: AuthRequestOptions }
Aunque estoy respondiendo esto muy tarde, pero si alguien está buscando una solución más fácil.
Podemos usar angular2-jwt. angular2-jwt es útil para adjuntar automáticamente un JSON Web Token (JWT) como encabezado de autorización cuando se realizan solicitudes HTTP desde una aplicación Angular 2.
Podemos establecer encabezados globales con la opción de configuración avanzada
Y enviando por solicitud token como
fuente
Me gusta la idea de anular las opciones predeterminadas, esto parece una buena solución.
Sin embargo, si estás dispuesto a extender la
Http
clase. ¡Asegúrate de leer esto!Algunas respuestas aquí en realidad muestran una sobrecarga incorrecta del
request()
método, lo que podría conducir a errores difíciles de detectar y un comportamiento extraño. Me he topado con esto yo mismo.Esta solución se basa en la
request()
implementación del método en Angular4.2.x
, pero debería ser compatible con el futuro:Tenga en cuenta que estoy importando la clase original de esta manera
import { Http as NgHttp } from '@angular/http';
para evitar conflictos de nombres.Y aquí está el ejemplo de cómo registrar esta clase anulada con el contenedor DI:
Con este enfoque, puede inyectar la
Http
clase normalmente, pero su clase anulada se inyectará mágicamente en su lugar. Esto le permite integrar su solución fácilmente sin cambiar otras partes de la aplicación (polimorfismo en acción).Simplemente agregue
httpProvider
a laproviders
propiedad de los metadatos de su módulo.fuente
El mas simple de todos
Crear un
config.ts
archivoLuego en tu
service
, solo importa elconfig.ts
archivoCreo que fue el más simple y el más seguro.
fuente
Hubo algunos cambios para angular 2.0.1 y superior:
fuente
Puedo elegir una solución más simple> Agregar nuevos encabezados a las opciones predeterminadas fusionar o cargar mediante su función api get (u otra).
Por supuesto, puede externalizar estos encabezados en las opciones predeterminadas o lo que sea en su clase. Esto se encuentra en la API de clase de exportación api.ts @Injectable () generada por Ionic {}
Es muy rápido y funciona para mí. No quería el formato json / ld.
fuente
Puedes usar
canActive
en tus rutas, así:Tomado de: https://auth0.com/blog/angular-2-authentication
fuente