OAuth 2.0 适用于 Google 表格,但不适用于 Google Calendar API

Posted

技术标签:

【中文标题】OAuth 2.0 适用于 Google 表格,但不适用于 Google Calendar API【英文标题】:OAuth 2.0 Works for Google Sheets but not for Google Calendar API 【发布时间】:2018-04-28 19:36:24 【问题描述】:

我正在使用 Google API 来读取/写入 Google 表格和 Google Drive API。 我最近被分配了一个需要发送日历邀请的项目。该网站是托管在 Apache Tomcat 8.5 上的 JSF 页面。对于其他 API,我使用的是服务帐户。 我现在尝试以同样的方式授权日历服务,但它失败了。第一行是对工作表服务的成功授权,它在日历服务上失败:

GoogleConnection:绝对路径:H:/ownCloud/Wabco/Workspace/WabcoDiagram/WebContent/resources/webserviceaccount.json GoogleConnection:绝对路径:H:/ownCloud/Wabco/Workspace/WabcoDiagram/WebContent/resources/webserviceaccount.json 线程“主”java.lang.NoSuchMethodError 中的异常:com.google.api.client.googleapis.services.json.AbstractGoogleJsonClient$Builder.setBatchPath(Ljava/lang/String;)Lcom/google/api/client/googleapis/services /AbstractGoogleClient$Builder; 在 com.google.api.services.calendar.Calendar$Builder.setBatchPath(Calendar.java:6758) 在 com.google.api.services.calendar.Calendar$Builder.(Calendar.java:6737) 在 de.promolitor.wabcodiagramviewer.audit.AuditGoogleCalendar.getCalendarServiceLocal(AuditGoogleCalendar.java:112) 在 de.promolitor.wabcodiagramviewer.audit.AuditGoogleCalendar.initializeCalendarServiceLocal(AuditGoogleCalendar.java:150) 在 de.promolitor.wabcodiagramviewer.audit.AuditGoogleCalendar.main(AuditGoogleCalendar.java:156)

我的问题: 我可以使用服务帐户登录 Google Calendar API,或者我必须做哪些更改,或者我的代码中是否还有其他错误?

我可以从 Web 服务服务帐户发送日历邀请,并让其他用户成为活动的管理员/创建者,以便他可以在必要时更改活动吗?这是否需要“域范围的权限”? 我在一家使用 GSuit 的公司工作。

示例代码。本地函数用于本地测试。

package de.promolitor.wabcodiagramviewer.audit;

import java.io.FileInputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;

import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.DateTime;
import com.google.api.services.calendar.Calendar;
import com.google.api.services.calendar.CalendarScopes;
import com.google.api.services.calendar.model.Event;
import com.google.api.services.calendar.model.Events;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.gmail.GmailScopes;
import com.google.api.services.plus.Plus;
import com.google.api.services.sheets.v4.Sheets;
import com.google.api.services.sheets.v4.SheetsScopes;

public class AuditGoogleCalendar 
    /** Application name. */
    private static final String APPLICATION_NAME = "Wabco Audit";

    /** Global instance of the @link FileDataStoreFactory. */
    // private static FileDataStoreFactory DATA_STORE_FACTORY;

    /** Global instance of the JSON factory. */
    private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();

    private static GoogleCredential credential;

    /** Global instance of the HTTP transport. */
    private static HttpTransport httpTransport;

    private static Plus plus;

    private static Sheets service;
    private static Drive driveService;
    private static Calendar calendarService;

    /**
     * Global instance of the scopes required by this quickstart.
     *
     * If modifying these scopes, delete your previously saved credentials at
     * ~/.credentials/sheets.googleapis.com-java-quickstart
     */
    private static final List<String> SCOPES = Arrays.asList(SheetsScopes.SPREADSHEETS, DriveScopes.DRIVE,
            GmailScopes.MAIL_GOOGLE_COM, CalendarScopes.CALENDAR);

    static 
        try 
            httpTransport = GoogleNetHttpTransport.newTrustedTransport();
         catch (Throwable t) 
            t.printStackTrace();
            System.exit(1);
        
    


    public static GoogleCredential authorize() throws IOException, GeneralSecurityException 
        String relativeWebPath = "/resources/" + "webserviceaccount.json";
        ServletContext servletContext = (ServletContext) FacesContext.getCurrentInstance().getExternalContext()
                .getContext();
        String absoluteDiskPath = servletContext.getRealPath(relativeWebPath);
        System.out.println("GoogleConnection: Absolut Path: " + absoluteDiskPath);

        GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream(absoluteDiskPath))
                .createScoped(SCOPES);
        return credential;
    

    public static GoogleCredential authorizeLocal() throws IOException, GeneralSecurityException 
        String absoluteDiskPath = "H:/ownCloud/Wabco/Workspace/WabcoDiagram/WebContent/resources/webserviceaccount.json";
        System.out.println("GoogleConnection: Absolut Path: " + absoluteDiskPath);

        GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream(absoluteDiskPath))
                .createScoped(SCOPES);
        return credential;

    

    public static Calendar getCalendarService() throws IOException, GeneralSecurityException 
        Credential credential = authorize();
        return new Calendar.Builder(httpTransport, JSON_FACTORY, credential).setApplicationName(APPLICATION_NAME)
                .build();
    

    public static Calendar getCalendarServiceLocal() throws IOException, GeneralSecurityException 
        Credential credential = authorizeLocal();
        return new Calendar.Builder(httpTransport, JSON_FACTORY, credential).setApplicationName(APPLICATION_NAME)
                .build();
    

    public static Sheets getSheetsService() throws IOException, GeneralSecurityException 
        credential = authorize();
        return new Sheets.Builder(httpTransport, JSON_FACTORY, credential).setApplicationName(APPLICATION_NAME).build();
    

    public static Sheets getSheetsServiceLocal() throws IOException, GeneralSecurityException 
        credential = authorizeLocal();
        return new Sheets.Builder(httpTransport, JSON_FACTORY, credential).setApplicationName(APPLICATION_NAME).build();
    

    public static Drive getDriveService() throws IOException, GeneralSecurityException 
        GoogleCredential credential = authorize();
        return new Drive.Builder(httpTransport, JSON_FACTORY, credential).setApplicationName(APPLICATION_NAME).build();
    

    public static void initializeSheetService() throws IOException, GeneralSecurityException 
        service = getSheetsService();
    

    public static void initializeSheetServiceLocal() throws IOException, GeneralSecurityException 
        service = getSheetsServiceLocal();
    

    public static void initializeDriveService() throws IOException, GeneralSecurityException 
        driveService = getDriveService();
    

    public static void initializeCalendarService() throws IOException, GeneralSecurityException 
        calendarService = getCalendarService();
    

    public static void initializeCalendarServiceLocal() throws IOException, GeneralSecurityException 
        calendarService = getCalendarServiceLocal();
    

    public static void main(String[] args) 
        try 
            initializeSheetServiceLocal();
            initializeCalendarServiceLocal();

         catch (Exception e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
        
    


【问题讨论】:

【参考方案1】:

我的问题:我可以使用服务帐户登录 Google 日历 API,或者我必须做哪些更改,或者我的代码中是否还有其他错误?

是的,您可以在 Google 日历中使用服务帐户。您的代码在我看来没问题,您只需添加您已完成的日历范围并在 Google 开发人员控制台中为服务帐户启用 google 日历 API。

我可以从 Web 服务服务帐户发送日历邀请,并让其他用户成为活动的管理员/创建者,以便他可以在必要时更改活动吗?这是否需要“域范围的权限”?我在一家使用 GSuit 的公司工作。

是的,您可以使用服务帐户。您必须让 Gsuit 管理员授予服务帐户访问日历的权限,然后它才能创建活动和邀请人员。是的,它需要“域范围的权限”?插入活动后,您应该能够修补活动并将其他人设置为组织者。 check this 我已经有一段时间没有做这件事了,所以抱歉。

【讨论】:

您好,感谢您的快速回复。我的代码适用于工作表 API,如果我对日历生成器执行相同操作,则会收到上面发布的错误。范围已添加,我还为帐户激活了日历 API。 > java.lang.NoSuchMethodError 似乎是错误的导入?但是当我在eclipse源代码上打开错误位置时,方法是存在的,所以我不确定是什么导致了问题。 我仔细检查了导入,但一切似乎都是正确的。它试图从方法返回:com/google/api/client/googleapis/services/AbstractGoogleClient$Builder,但找不到作为方法?我在这里做错了什么? 好的,错误是由依赖项之一的版本不匹配造成的。我得到了最新的依赖项并清理了项目,错误消失了。我应该切换到 Maven 或 gradle。 ;-) 感谢您对我的其他问题的帮助!

以上是关于OAuth 2.0 适用于 Google 表格,但不适用于 Google Calendar API的主要内容,如果未能解决你的问题,请参考以下文章

如何使用适用于 Web 服务器应用程序的 Google OAuth 2.0 向 Google ID_Token 添加自定义声明

将 OAuth 2.0 和 Google 电子表格 API 与 Java 结合使用的示例是啥?

从 Google OAuth 2.0 PHP API 获取用户信息

OAuth 2.0介绍

OAuth 2.0

理解OAuth 2.0