Reputation: 491
In an existing Java based spring boot application, I have integrated Google calendar API. In my local, it works. On dev server, I see that the URL to open in browser is :
https://accounts.google.com/o/oauth2/auth?access_type=offline&client_id=xxx.apps.googleusercontent.com&redirect_uri=http://localhost:8080/Callback&response_type=code&scope=https://www.googleapis.com/auth/calendar.events
where the redirect uri is http://localhost:8080/Callback instead of https://dev.myserver.in/Callback which results in invalid request
even if I correct the URI manually and past in the browser, it says 404.
I have created the service account and provided redirect uris for localhost and my dev server, and I am using the same as credential.json file in my code.
Following are code snippets
private Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT) throws IOException {
// Load client secrets.
InputStream in = GoogleCalendarServiceImpl.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
if (in == null) {
throw new FileNotFoundException("Resource not found: " + CREDENTIALS_FILE_PATH);
}
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
// Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY,
clientSecrets, SCOPES)
.setDataStoreFactory(new FileDataStoreFactory(new java.io.File(tokensDirectoryPath)))
.setAccessType("offline")
.build();
LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8888).build(); //.Builder().setPort(localServerReceiverPort).build();
return new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
}
and here it is used:
public void createEvent(CreateEventRequest request) throws GeneralSecurityException, IOException {
// Build a new authorized API client service.
final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
Calendar service = new Calendar.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
.setApplicationName(APPLICATION_NAME).build();
Event event = createEvent(request);
String calendarId = "primary";
Event createdEvent = service.events().insert(calendarId, event).execute();
log.info("Event successfully created! : {} ", createdEvent.getHtmlLink());
}
Here are the configs :
private static final String APPLICATION_NAME = "Calendar";
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private static final String CREDENTIALS_FILE_PATH = "/credential.json";
@Value("${google.calendar.tokens.directory.path}")
private String tokensDirectoryPath
/**
* Global instance of the scopes required by this quickstart. If modifying these
* scopes, delete your previously saved tokens/ folder.
*/
private static final List<String> SCOPES = Collections.singletonList(CalendarScopes.CALENDAR_EVENTS);
Upvotes: 1
Views: 442
Reputation: 117244
You are using
new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
This is for use with installed applications. Installed applications use localhost as the redirect uri.
For web server aplcistons you should be using GoogleAuthorizationCodeFlow
public class CalendarServletSample extends AbstractAuthorizationCodeServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
// do stuff
}
@Override
protected String getRedirectUri(HttpServletRequest req) throws ServletException, IOException {
GenericUrl url = new GenericUrl(req.getRequestURL().toString());
url.setRawPath("/oauth2callback");
return url.build();
}
@Override
protected AuthorizationCodeFlow initializeFlow() throws IOException {
return new GoogleAuthorizationCodeFlow.Builder(
new NetHttpTransport(), GsonFactory.getDefaultInstance(),
"[[ENTER YOUR CLIENT ID]]", "[[ENTER YOUR CLIENT SECRET]]",
Collections.singleton(CalendarScopes.CALENDAR)).setDataStoreFactory(
DATA_STORE_FACTORY).setAccessType("offline").build();
}
@Override
protected String getUserId(HttpServletRequest req) throws ServletException, IOException {
// return user ID
}
}
public class CalendarServletCallbackSample extends AbstractAuthorizationCodeCallbackServlet {
@Override
protected void onSuccess(HttpServletRequest req, HttpServletResponse resp, Credential credential)
throws ServletException, IOException {
resp.sendRedirect("/");
}
@Override
protected void onError(
HttpServletRequest req, HttpServletResponse resp, AuthorizationCodeResponseUrl errorResponse)
throws ServletException, IOException {
// handle error
}
@Override
protected String getRedirectUri(HttpServletRequest req) throws ServletException, IOException {
GenericUrl url = new GenericUrl(req.getRequestURL().toString());
url.setRawPath("/oauth2callback");
return url.build();
}
@Override
protected AuthorizationCodeFlow initializeFlow() throws IOException {
return new GoogleAuthorizationCodeFlow.Builder(
new NetHttpTransport(), GsonFactory.getDefaultInstance()
"[[ENTER YOUR CLIENT ID]]", "[[ENTER YOUR CLIENT SECRET]]",
Collections.singleton(CalendarScopes.CALENDAR)).setDataStoreFactory(
DATA_STORE_FACTORY).setAccessType("offline").build();
}
@Override
protected String getUserId(HttpServletRequest req) throws ServletException, IOException {
// return user ID
}
}
Also ensure that you created Web application credentials On google cloud console and not installed application credentials.
Upvotes: 2