Actualmente uso un servicio Angular para todas mis llamadas a la API de back-end. Estas llamadas a la API deben enviar un token como parte de su encabezado de autorización. Para verificar que tengo un token de acceso válido, necesito verificarlo y posiblemente actualizarlo si ha caducado.
Estoy usando la versión más reciente de Amplify/Congito para mi autenticación.
Según lo que he buscado hasta ahora, la mejor manera de obtener el token y actualizar el accessToken si está vencido es ejecutar lo siguiente:
async handleToken () { try { const cognitoUser = await Auth.currentAuthenticatedUser(); const currentSession = cognitoUser.signInUserSession; cognitoUser.refreshSession(currentSession.refreshToken, (err, session) => { return session.accessToken.jwtToken }); } catch (e) { } }Esto devolverá el token de acceso actual o recién actualizado para enviar.
Mi problema es que no sé cómo puedo asegurarme de llamar a esto antes de cada llamada a la API para asegurarme de enviar el token más reciente.
Después de buscar más, descubrí que esto no se puede lograr a través de OnInit o en el constructor.
Este es un ejemplo de una llamada a la API.
getCustomerList(): Observable<CustomerList[]> { this.handleToken(); const url = hosturl +'c_l'; const httpOptions = { headers: new HttpHeaders({ 'Access-Control-Allow-Origin': '*', 'Content-Type': 'application/json', 'Authorization': ls || '{}' }), withCredentials: true, params: { 'clientid': clientid } }; return this._http.get(url, httpOptions) .pipe( map((res) => { console.log(res); return <CustomerList[]> res; }), catchError(err => throwError(this.handleError(err))), ); }Tenga en cuenta que esto ejecutará handleToken correctamente, pero no es asíncrono debido a que la función que lo llama no usa await.
Cualquier consejo sería apreciado.
No tengo idea de por qué necesita llamar a esta función en cada llamada a la API, en lugar de almacenar el token en localStorage y obtenerlo desde allí para inyectarlo en cada llamada a la API. De todos modos, puede crear su propio interceptor (que inspecciona y transforma las solicitudes HTTP de su aplicación a un servidor), luego inyecta el token en el encabezado de las solicitudes de la siguiente manera:
// import { from, Observable } from 'rxjs'; // import { switchMap } from 'rxjs/operators'; @Injectable() export class AuthInterceptor implements HttpInterceptor { intercept( req: HttpRequest<any>, next: HttpHandler ): Observable<HttpEvent<any>> { // Use RxJS `from` function to convert `Promise` to an `Observable`: return from(this.handleToken()).pipe( // Use RxJS `switchMap` operator to map the token's Observable to the next.handle one: switchMap((token) => { // Inject the token into the request's header, and pass it to the next request handler: return next.handle( req.clone({ headers: req.headers.set('Authorization', `Bearer ${token}`), }) ); }) ); } // Update the handleToken function to return a `Promise`: handleToken(): Promise<string> { return Auth.currentAuthenticatedUser().then((cognitoUser) => cognitoUser.refreshSession( cognitoUser.signInUserSession.refreshToken, (err, session) => { return session.accessToken.jwtToken; } ) ); } }Lea más sobre cómo crear su propio interceptor aquí: https://angular.io/guide/http#intercepting-requests-and-responses