Can I use token from FE, where user is authorized from Google to insert event into google calendar on backend? Flow is:
- user uthorized by google on frontend (firebase and google)
- fill form on FE and submit
- on backend side save data into DB and post event on calendar
Can I reuse token from FE? How I can do that?
I try few solutions using GoogleAuthorizationCodeFlow
, and every time I get HTTP 401 or link to authorization in logs…
Currently creation of service looks like:
protected void initialize() { GoogleClientSecrets clientSecrets = createClientSecrets(); GoogleAuthorizationCodeFlow flow = createGoogleAuthorizationCode(clientSecrets); LocalServerReceiver receiver = createReceiver(); Credential credential = createCredentials(flow, receiver); // here I get link to authorization in google :( credential.setAccessToken(getAccessToken()); service = createCalendarClientService(credential); } private GoogleAuthorizationCodeFlow createGoogleAuthorizationCode(GoogleClientSecrets clientSecrets) { try { return new GoogleAuthorizationCodeFlow.Builder( HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES) .setDataStoreFactory(new MemoryDataStoreFactory()) .setAccessType("online") .build(); } catch (IOException e) { throw new RuntimeException(e); } } private LocalServerReceiver createReceiver() { return new LocalServerReceiver.Builder() .setPort(port) .build(); } private Credential createCredentials(GoogleAuthorizationCodeFlow flow, LocalServerReceiver receiver) { try { return new AuthorizationCodeInstalledApp(flow, receiver) .authorize("user"); } catch (IOException e) { throw new RuntimeException(e); } } private Calendar createCalendarClientService(Credential credential) { return new Calendar.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential) .setApplicationName(APPLICATION_NAME) .build(); }
Advertisement
Answer
Ok. I’ve found out how to do. First. Authorization with access token should be on front-end. I use angular and firebase for uthorization.
- install
gapi
andgapi.auth2
- create on google (https://console.cloud.google.com) app and authorization data for web client (OAuth 2.0)
- then I authorize user in google
as below:
private async loginWithGoogle(): Promise<void> { await this.initializeGoogleApi(); const googleAuth = gapi.auth2.getAuthInstance(); if (!this.isLoggedWithGoogle()) { const googleUser = await googleAuth.signIn(); sessionStorage.setItem(this.GOOGLE_ID_TOKEN, googleUser.getAuthResponse().id_token); sessionStorage.setItem(this.GOOGLE_ACCESS_TOKEN, googleUser.getAuthResponse().access_token); } const credential = firebase.auth.GoogleAuthProvider.credential(this.googleToken); await this.angularFireAuth.signInWithCredential(credential); } private isLoggedWithGoogle(): boolean { return !!sessionStorage.getItem(this.GOOGLE_ID_TOKEN); } private async initializeGoogleApi(): Promise<void> { return new Promise(resolve => { gapi.load('client', () => { gapi.client.init(environment.calendarConfig); gapi.client.load('calendar', 'v3', () => { resolve(); }); }); }); }
now I send acces token with header to back-end and there I can insert event on google or do whatever I want.
public String insertEvent(Event event, String accessToken) { try { initialize(accessToken); return service.events() .insert(CALENDAR_ID, event) .execute() .getId(); } catch (IOException e) { throw new RuntimeException(e); } } private void initialize(String accessToken) { Credential credential = createCredentials(accessToken); service = createCalendarClientService(credential); } private Credential createCredentials(String accessToken) { return new GoogleCredential().setAccessToken(accessToken); }