运行Google示例代码出现PERMISSION_DENIED错误,不知何处插入API凭据
解决 "The request is missing a valid API key." 错误 & 凭据配置指南
先给你理清楚问题根源:你看到的这个错误,要么是你用的API需要API Key(而非你创建的OAuth客户端ID),要么是你在使用OAuth授权时没把客户端凭据正确配置到代码里。结合你给出的代码里用到了GoogleCredential,大概率是后者的配置问题,下面分两种情况给你一步步解决:
情况1:你的API需要API Key(比如Google Maps、YouTube Data API公共访问场景)
如果是不需要用户登录授权的公共API,直接把你的API Key加到请求里就行:
- 找到你构建API客户端的代码段,比如这样加:
// 举个YouTube Data API的例子 YouTube youtube = new YouTube.Builder(httpTransport, jsonFactory, null) .setApplicationName("你的应用名称") .setYouTubeRequestInitializer(new YouTubeRequestInitializer("你的API_KEY")) .build(); - 要是你直接拼HTTP请求URL,就在末尾加
?key=你的API_KEY就行。
情况2:你的API需要OAuth 2.0授权(比如Drive、Gmail这类需要用户权限的API)
你的代码里已经引入了GoogleCredential,说明是这个场景。你需要把创建的客户端ID、密钥配置到代码里,步骤如下:
先准备凭据文件
去Google Cloud控制台下载你的OAuth客户端凭据JSON文件(一般叫credentials.json),把它放到你Java项目的资源目录下(比如src/main/resources)。修改代码加载凭据
替换掉你原来的Credential初始化逻辑,用下面的代码来获取授权后的凭据:import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow; import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets; import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.client.googleapis.auth.oauth2.LocalServerReceiver; 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.gson.GsonFactory; import com.google.api.client.util.store.FileDataStoreFactory; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Arrays; import java.util.List; public class YourClassName { // 替换成你的应用名称 private static final String APPLICATION_NAME = "你的应用名称"; private static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance(); // 令牌保存目录,第一次授权后会自动创建 private static final String TOKENS_DIRECTORY_PATH = "tokens"; // 替换成你需要访问的API权限范围,比如Drive只读权限 private static final List<String> SCOPES = Arrays.asList("https://www.googleapis.com/auth/drive.readonly"); // 凭据文件的路径,对应你放到资源目录的credentials.json private static final String CREDENTIALS_FILE_PATH = "/credentials.json"; // 获取授权后的GoogleCredential private static GoogleCredential getCredentials(final HttpTransport HTTP_TRANSPORT) throws IOException { // 加载凭据文件 InputStream in = YourClassName.class.getResourceAsStream(CREDENTIALS_FILE_PATH); if (in == null) { throw new FileNotFoundException("没找到凭据文件,请检查路径:" + CREDENTIALS_FILE_PATH); } GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in)); // 构建授权流程 GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder( HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES) .setDataStoreFactory(new FileDataStoreFactory(new File(TOKENS_DIRECTORY_PATH))) .setAccessType("offline") // 允许离线访问,下次不用重新授权 .build(); // 本地服务器接收授权回调,端口可以自己改,但要和控制台配置的一致 LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8888).build(); return new AuthorizationCodeInstalledApp(flow, receiver).authorize("user"); } public static void main(String... args) throws Exception { // 初始化HTTP传输 HttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport(); // 获取已授权的凭据 GoogleCredential credential = getCredentials(HTTP_TRANSPORT); // 示例:初始化Drive API客户端,替换成你要用的API Drive service = new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential) .setApplicationName(APPLICATION_NAME) .build(); // 接下来就可以调用API接口了... } }最后检查几个关键点
- 确保你在Google Cloud控制台已经启用了对应的API(比如要调用Drive API,必须先在控制台找到它并启用)
- 本地测试的话,要把OAuth客户端的授权回调URL设置为
http://localhost:8888/(和代码里的端口一致) - 第一次运行代码时,会自动弹出浏览器让你登录Google账号授权,授权后会生成
tokens目录保存令牌,后续运行就不用重复授权了
内容的提问来源于stack exchange,提问作者Cristiano Felipe
相关产品推荐
相关产品推荐

