Spring Boot集成Google Drive API v3实现一次认证自动刷新令牌咨询
解决方案
完全可以基于Google Drive API v3实现一次授权后自动刷新access token,你的现有代码已经包含核心实现逻辑,仅需少量调整即可稳定运行。
核心原理
Google OAuth2授权流程中,只要申请授权时指定access_type=offline参数,首次授权成功后即可获取到长期有效的refresh_token,Google官方Java客户端库会自动处理access_token过期后的刷新逻辑,无需手动编写刷新代码。
现有代码优势
- 已经在
GoogleAuthorizationCodeFlow构建逻辑中设置了.setAccessType("offline"),满足获取refresh_token的前提条件 - 配置了
FileDataStoreFactory,会自动将授权获取到的access_token、refresh_token持久化存储到指定的tokens目录,服务重启无需重复授权
优化方案
你当前的代码每次调用上传接口都会重复初始化授权流程和Drive实例,效率极低,建议将Drive实例改为单例,服务启动时仅初始化一次,优化后代码如下:
@Service public class GoogleDriveService { private static final String APPLICATION_NAME = "application name"; private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance(); private static final String TOKENS_DIRECTORY_PATH = "tokens"; private static final List<String> SCOPES = Collections.singletonList(DriveScopes.DRIVE); private static final String CREDENTIALS_FILE_PATH = "/client_secret.json"; // Drive实例做成单例全局复用 private Drive driveService; // 服务启动时初始化一次Drive实例 @PostConstruct public void initDriveService() throws GeneralSecurityException, IOException { final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport(); Credential credential = getCredentials(HTTP_TRANSPORT); this.driveService = new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential) .setApplicationName(APPLICATION_NAME) .build(); } private Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT) throws IOException { InputStream in = GoogleDriveService.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 java.io.File(TOKENS_DIRECTORY_PATH))) .setAccessType("offline") // 新增配置,确保首次授权时强制返回refresh_token .setApprovalPrompt("force") .build(); LocalServerReceiver receiver = new LocalServerReceiver.Builder().setHost("127.0.0.1").setPort(8089).build(); return new AuthorizationCodeInstalledApp(flow, receiver).authorize("user"); } public boolean uploadGoogleDriveFile(java.io.File originalFile){ try { File file = new File(); file.setName(originalFile.getName()); FileContent content = new FileContent("text/plain", originalFile); File uploadedFile = driveService.files().create(file, content).setFields("id").execute(); System.out.println("文件ID: " + uploadedFile.getId()); return true; } catch (IOException e) { e.printStackTrace(); return false; } } }
注意事项
- 首次启动服务时,控制台会输出授权链接,访问链接完成一次授权即可,授权成功后
tokens目录会生成凭证文件,后续启动/调用接口无需重复授权 - 服务器部署时需保证
tokens目录拥有读写权限,避免凭证文件无法正常读写 - 若调整过授权范围,需删除
tokens目录下的旧凭证文件,重新走一次授权流程 - 若之前授权过未拿到refresh_token,删除旧凭证重新授权即可
内容的提问来源于stack exchange,提问作者Wani
相关产品推荐
相关产品推荐

