
本教程旨在指导 java 应用程序如何通过 google oauth 2.0 授权代码流获取用户访问令牌。针对直接使用 `googlecredentials.builder` 遇到的权限问题,本文将介绍正确的依赖配置、`client_secrets.json` 文件创建,并提供使用 `googleauthorizationcodeflow` 实现交互式用户认证的完整代码示例,最终安全地获取并管理访问令牌,助力开发者顺利集成 google api。
引言:理解 Google OAuth 2.0 认证挑战
在 Java 应用程序中与 Google API 进行交互时,获取用户授权的访问令牌是关键一步。许多开发者在尝试直接使用 com.google.auth.oauth2.GoogleCredentials.Builder 配合 clientId 和 clientSecret 获取访问令牌时,可能会遇到 Builder() 方法受保护的访问权限问题。这是因为 GoogleCredentials.Builder 主要设计用于服务账户认证或在已拥有刷新令牌等凭据时构建 GoogleCredentials 对象,而非用于启动交互式的用户授权流程。
对于需要用户通过浏览器进行认证并授予应用程序访问权限的场景(例如桌面应用程序或自动化脚本),Google 推荐使用 OAuth 2.0 授权代码流(Authorization Code Flow)。本文将详细介绍如何正确配置项目、实现这一流程,并安全地获取所需的 Google 访问令牌。
项目依赖配置
为了实现 Google OAuth 2.0 授权代码流,我们需要在项目的 pom.xml 文件中添加以下 Maven 依赖。这些库提供了处理 OAuth 流程、HTTP 请求以及 JSON 解析所需的功能。
com.google.api-client google-api-client 1.32.1 com.google.oauth-client google-oauth-client 1.32.1 com.google.oauth-client google-oauth-client-jetty 1.32.1 com.google.http-client google-http-client-jackson2 1.39.2 com.google.oauth-client google-oauth-client-java6 1.32.1
请注意,版本号可能需要根据最新的稳定版本进行调整。
立即学习“Java免费学习笔记(深入)”;
Veed AI Voice Generator
Veed推出的AI语音生成器
77 查看详情
配置客户端密钥:client_secrets.json
出于安全性和最佳实践考虑,您的 clientId 和 clientSecret 不应硬编码在源代码中。Google 推荐将这些凭据存储在一个名为 client_secrets.json 的文件中。
1. 从 Google Cloud 控制台获取凭据
访问 Google Cloud 控制台 (console.cloud.google.com)。选择或创建一个项目。导航到 “API 和服务” -> “凭据”。点击 “创建凭据”,选择 “OAuth 客户端 ID”。选择 “桌面应用” 作为应用程序类型,然后创建。创建后,您将获得客户端 ID 和客户端密钥。点击 “下载 JSON” 按钮,下载的文件通常就是 client_secret_.json。将其重命名为 client_secrets.json。
2. client_secrets.json 文件结构
下载的 client_secrets.json 文件通常具有以下结构:
{ "web": { // 如果您选择的是“Web 应用”类型,这里是 "web" "client_id": "YOUR_CLIENT_ID.apps.googleusercontent.com", "project_id": "your-project-id", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_secret": "YOUR_CLIENT_SECRET", "redirect_uris": [ "http://localhost" // 或其他配置的重定向 URI ] }, "installed": { // 如果您选择的是“桌面应用”类型,这里是 "installed" "client_id": "YOUR_CLIENT_ID.apps.googleusercontent.com", "project_id": "your-project-id", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_secret": "YOUR_CLIENT_SECRET", "redirect_uris": [ "http://localhost" ] }}
请确保您的 client_secrets.json 文件位于项目的类路径下(例如 src/main/resources 目录),以便程序可以加载它。
实现 Google OAuth 2.0 授权代码流
以下是使用 Java 实现 Google OAuth 2.0 授权代码流的完整代码示例。此示例将引导用户在浏览器中完成认证,然后应用程序将接收授权代码并交换为访问令牌。
package com.example.googleauth;import com.google.api.client.auth.oauth2.Credential;import com.google.api.client.extensions.java6.auth.oauth2.FileDataStoreFactory;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.http.HttpTransport;import com.google.api.client.json.JsonFactory;import com.google.api.client.json.jackson2.JacksonFactory;import com.google.api.client.util.store.DataStoreFactory;import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;import java.io.File;import java.io.IOException;import java.io.InputStreamReader;import java.security.GeneralSecurityException;import java.util.Collections;import java.util.List;public class GoogleTokenFetcher { /** 应用程序名称,用于标识用户代理 */ private static final String APPLICATION_NAME = "Google Token Fetcher"; /** JSON 工厂,用于解析 JSON 响应 */ private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance(); /** HTTP 传输器 */ private static HttpTransport HTTP_TRANSPORT; /** 数据存储工厂,用于持久化凭据(如刷新令牌) */ private static FileDataStoreFactory DATA_STORE_FACTORY; /** * 定义应用程序所需的授权范围(Scopes)。 * 这里以访问 Google 日历为例,您可以根据需要更改。 * 更多 Scope 请参考 Google API 文档。 */ private static final List SCOPES = Collections.singletonList("https://www.googleapis.com/auth/calendar.readonly"); // 如果需要访问用户个人资料,可以使用 "https://www.googleapis.com/auth/userinfo.profile" // 或 "https://www.googleapis.com/auth/userinfo.email" // 甚至更通用的 "https://www.googleapis.com/auth/drive.readonly" 等 static { try { HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport(); // 凭据将存储在用户主目录下的 .store/google_token_fetcher 目录中 DATA_STORE_FACTORY = new FileDataStoreFactory(new File(System.getProperty("user.home"), ".store/google_token_fetcher")); } catch (GeneralSecurityException | IOException e) { e.printStackTrace(); System.exit(1); } } public static void main(String[] args) throws IOException { try { Credential credential = authorize(); if (credential != null && credential.getAccessToken() != null) { String accessToken = credential.getAccessToken(); System.out.println("成功获取访问令牌 (Access Token): " + accessToken); // 您可以使用这个访问令牌调用 Google API // 例如: // Calendar service = new Calendar.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential) // .setApplicationName(APPLICATION_NAME) // .build(); // Event event = service.events().get("primary", "eventId").execute(); // System.out.println("获取到的事件:" + event.getSummary()); } else { System.out.println("未能获取访问令牌。"); } } catch (Exception e) { System.err.println("授权过程中发生错误: " + e.getMessage()); e.printStackTrace(); } } /** * 授权安装的应用程序访问用户的受保护数据。 * @return Credential 对象,包含访问令牌和刷新令牌 * @throws Exception 如果授权过程中发生错误 */ private static Credential authorize() throws Exception { // 1. 加载客户端密钥 (client_secrets.json) // 确保 client_secrets.json 文件在类路径中 (例如 src/main/resources) GoogleClientSecrets clientSecrets = GoogleClientSecrets.load( JSON_FACTORY, new InputStreamReader(GoogleTokenFetcher.class.getResourceAsStream("/client_secrets.json")) ); // 2. 设置授权代码流 GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder( HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES // 应用程序所需的权限范围 ) .setDataStoreFactory(DATA_STORE_FACTORY) // 用于持久化凭据,例如刷新令牌 .setAccessType("offline") // 请求刷新令牌,以便在访问令牌过期后重新获取 .build(); // 3. 授权用户 // LocalServerReceiver 会在本地启动一个服务器,监听 Google 授权回调 LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8888).build(); // 可以指定端口 return new AuthorizationCodeInstalledApp(flow, receiver).authorize("user"); }}
代码解析:
静态初始化块 (static {}): 初始化 HttpTransport 和 DataStoreFactory。GoogleNetHttpTransport.newTrustedTransport() 用于创建安全的 HTTP 传输层。FileDataStoreFactory 用于将用户的凭据(包括刷新令牌)持久化存储在本地文件系统中,避免每次运行时都要求用户重新授权。SCOPES: 定义了应用程序需要访问用户数据的权限范围。请务必根据您的应用程序实际需求选择合适的 Scope。authorize() 方法:加载 client_secrets.json: 使用 GoogleClientSecrets.load() 从类路径加载 client_secrets.json 文件。构建 GoogleAuthorizationCodeFlow: 这是 OAuth 2.0 授权代码流的核心
以上就是Java 应用中获取 Google OAuth 2.0 访问令牌的实用指南的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/862231.html
微信扫一扫
支付宝扫一扫