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:
JavaScript
x
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:
JavaScript
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.
JavaScript
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);
}