Skip to content
Advertisement

Google calendar api – can I reuse token form google?

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 and gapi.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);
}
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement