Piotr Sobuś
Piotr Sobuś

Reputation: 322

How to re-authenticate a user in Firebase?

Currently, me and my team are trying to develop a fully working re-authentication mechanism. We came across a problem with getting a new token from Firebase. Firstly, we let people to log-in with Google, the code looks like this:

loginUserWithGoogle(): Promise<any> {
    const provider = new firebase.auth.GoogleAuthProvider();
    provider.addScope('https://mail.google.com');
    return this._af.auth.signInWithPopup(provider);
}

After the user logs in, we have the access_token and refresh_token. The user has possibilty to see his own e-mails from Gmail thanks to Gmail API and GAPI library.

 gapi.load('client', () => {
        gapi.client.setToken({access_token: <SAVED ACCESS TOKEN>});
        gapi.client.init({
            apiKey: '<API KEY>',
            clientId: '<CLIENT ID>',
            discoveryDocs: ['https://www.googleapis.com/discovery/v1/apis/gmail/v1/rest'],
            scope: 'https://mail.google.com/'
        });

        gapi.client.load('gmail', 'v1', () => {
            ...
        })
})

This works perfectly, but the access_token has an expiration time set to 1 hour. After that time, we receive 403 error code from Gmail API. So what we do is, we send a POST request (with query parameters grant_type=refresh_token&refresh_token=REFRESH_TOKEN) to...

https://securetoken.googleapis.com/v1/token?key=YOUR_API_KEY

... and we receive a new token and replace the old token with the new one. After comparing the 2 tokens (1 originally received from Firebase, 1 received from API) we came to a conclusion that those 2 tokens are completely different and we still receive 403 error after the replacement.

Is there a way to re-authenticate an user with Firebase?

Upvotes: 1

Views: 358

Answers (2)

Piotr Sobuś
Piotr Sobuś

Reputation: 322

DONE: The only solution that worked is integrating Gapi JavaScript Client with Firebase and creating an interval that runs every 30 minutes and triggers a function that refreshes the access token:

gapi.auth2.getAuthInstance().currentUser.get().reloadAuthResponse().then((currUser: any) => {
      // do something with currUser.access_token (new access token)
});

Upvotes: 0

varman
varman

Reputation: 8894

I've overcome this situation using interceptor. Every time when it requests data, firebase automatically generates token.

@Injectable()
export class HttpConfigInterceptor implements HttpInterceptor {
    constructor(private firebaseAuth: AngularFireAuth) {     
    }

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

        return this.firebaseAuth.idToken.pipe(
            mergeMap((token: any) => {

                if (token) {
                    request = request.clone({ headers: request.headers.set('X-Authorization-Firebase', token) });
                }

                return next.handle(request).pipe(
                    map((event: HttpEvent<any>) => {
                        if (event instanceof HttpResponse) {

                            console.log("event---> ", event)                            
                        }
                        return event;
                    }), catchError((error: HttpErrorResponse) => {

                        return throwError(error);
                }));

        }));
    }
}

Upvotes: 0

Related Questions