You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用Google Calendar API时触发GoogleJsonResponseException 401 Unauthorized错误

Fixing 401 Unauthorized ("Login Required") with Google Calendar API and Simple API Key

That 401 error is a common gotcha when working with the Google Calendar API—here's why it’s happening and how to fix it:

Root Cause

A simple API key only works for accessing public, unauthenticated resources in Google APIs. Google Calendar data (especially user-specific calendars like your own "primary" calendar) is private, so the API needs to verify you have permission to access it. API keys don’t provide user identity or authorization, hence the "Login Required" message.

Solutions

1. Use OAuth 2.0 Authentication (For Private/User-Specific Calendars)

This is the standard approach for accessing private calendar data. Here’s how to set it up:

  • Open the Google Cloud Console, navigate to your project, and go to APIs & Services > Credentials.
  • Create an OAuth 2.0 Client ID (select "Desktop app" as the application type if you’re running a local script).
  • Download the client secret JSON file and place it in your project directory.
  • Update your code to use the OAuth flow instead of the API key. Here’s a Java example matching your error’s stack trace:
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.calendar.Calendar;
import com.google.api.services.calendar.CalendarScopes;

import java.io.FileReader;
import java.util.Collections;

public class CalendarApiExample {
    private static final String APPLICATION_NAME = "Your App Name";
    private static final JacksonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
    private static final String TOKENS_DIRECTORY_PATH = "tokens";

    public static void main(String[] args) throws Exception {
        // Load client secrets from downloaded JSON
        GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new FileReader("client_secret.json"));

        // Build OAuth flow with read-only scope (adjust to CALENDAR for write access)
        GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
                GoogleNetHttpTransport.newTrustedTransport(), JSON_FACTORY, clientSecrets,
                Collections.singleton(CalendarScopes.CALENDAR_READONLY))
                .setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
                .setAccessType("offline") // Store token for future use
                .build();
        
        // Trigger browser-based authorization
        LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8888).build();
        Credential credential = new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");

        // Initialize Calendar service with authenticated credential
        Calendar service = new Calendar.Builder(GoogleNetHttpTransport.newTrustedTransport(), JSON_FACTORY, credential)
                .setApplicationName(APPLICATION_NAME)
                .build();

        // Example: Fetch upcoming events from primary calendar
        com.google.api.services.calendar.model.Events events = service.events().list("primary")
                .setMaxResults(10)
                .setTimeMin(new com.google.api.client.util.DateTime(System.currentTimeMillis()))
                .setOrderBy("startTime")
                .setSingleEvents(true)
                .execute();
    }
}

2. Use API Key Only For Public Calendars

If you’re targeting a public calendar (like a global holiday calendar), ensure:

  • The calendar is marked public in Google Calendar settings (share it with "Make available to public" and grant "See all event details" permissions).
  • Your API key is restricted to the Google Calendar API (in Cloud Console, edit your API key and add the Calendar API under "Restrict key to APIs").
  • Use the public calendar ID in your request (e.g., en.usa#holiday@group.v.calendar.google.com for US holidays).

Key Takeaway

API keys are great for public data, but any private user-specific data in Google APIs requires OAuth 2.0 to authenticate and authorize access. The OAuth flow will prompt you to log in with your Google account and grant permissions to your app, which resolves the 401 error.

内容的提问来源于stack exchange,提问作者nairavs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:36:43