如何通过Java代码获取访问google应用程序的临时持久凭据

如何通过Java代码获取访问google应用程序的临时持久凭据,java,google-api,google-drive-api,google-oauth,google-sheets-api,Java,Google Api,Google Drive Api,Google Oauth,Google Sheets Api,我正在使用google drive/sheets/oauth API Java进行独立应用程序的实践 我现在的重点是客户机身份验证。 我在GoogleDeveloper控制台上注册了我的应用程序,并获得了客户端json文件 下面是验证代码片段 /** Directory to store user credentials for this application. */ private static final java.io.File DATA_STORE_DIR = ResourceLoa

我正在使用google drive/sheets/oauth API Java进行独立应用程序的实践

我现在的重点是客户机身份验证。 我在GoogleDeveloper控制台上注册了我的应用程序,并获得了客户端json文件

下面是验证代码片段

/** Directory to store user credentials for this application. */

private static final java.io.File DATA_STORE_DIR = ResourceLoader.googleCredentials();

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

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

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

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

static {
    try {
        HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
        DATA_STORE_FACTORY = new FileDataStoreFactory(DATA_STORE_DIR);
    } catch (Throwable t) {
        MyLogger.getLogger().severe(t);
    }
}


/**
 * Creates an authorized Credential object.
 * @return an authorized Credential object.
 * @throws IOException
 */
private Credential authorize() throws IOException {
    // Load client secrets.
    //InputStream in = GDriveQuickStart.class.getResourceAsStream("/client_secret.json");

    Credential credential = null;

        InputStream in = new FileInputStream(ResourceWorking.googleClientSecretPath());

        GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));

        MyLogger.getLogger().info(clientSecrets.getDetails().toPrettyString());

        // Build flow and trigger user authorization request.
        GoogleAuthorizationCodeFlow flow =
                new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
                .setDataStoreFactory(DATA_STORE_FACTORY)
                .setAccessType("offline")
                .build();
        credential = new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");

        MyLogger.getLogger().info(credential.getAccessToken()+" "+credential.getRefreshToken()+" "+credential.getExpirationTimeMilliseconds()+" "+credential.getExpiresInSeconds());

    return credential;
}
/**用于存储此应用程序的用户凭据的目录*/
private static final java.io.File DATA_STORE_DIR=ResourceLoader.googleCredentials();
/**{@link FileDataStoreFactory}的全局实例*/
私有静态数据存储工厂数据存储工厂;
/**JSON工厂的全局实例*/
私有静态最终JsonFactory JSON_FACTORY=JacksonFactory.getDefaultInstance();
/**HTTP传输的全局实例*/
专用静态HttpTransport HTTP_传输;
/**此快速启动所需作用域的全局实例。
*
*如果修改这些作用域,请删除以前保存的凭据
*位于~/.credentials/drive java quickstart
*/
私有静态最终列表作用域=
Arrays.asList(DriveScopes.DRIVE);
静止的{
试一试{
HTTP_TRANSPORT=GoogleNetHttpTransport.newTrustedTransport();
DATA\u STORE\u FACTORY=新文件datastorefactory(DATA\u STORE\u DIR);
}捕获(可丢弃的t){
MyLogger.getLogger()严重(t);
}
}
/**
*创建授权凭据对象。
*@返回授权凭证对象。
*@抛出异常
*/
私有凭据授权()引发IOException{
//加载客户端机密。
//InputStream in=GDriveQuickStart.class.getResourceAsStream(“/client\u secret.json”);
凭证=空;
InputStream in=新文件InputStream(ResourceWorking.googleClientSecretPath());
GoogleClientSecrets clientSecrets=GoogleClientSecrets.load(JSON_工厂,新的InputStreamReader(in));
MyLogger.getLogger().info(clientSecrets.getDetails().toPrettyString());
//生成流并触发用户授权请求。
GoogleAuthorizationCodeFlow=
新的GoogleAuthorizationCodeFlow.Builder(HTTP_传输、JSON_工厂、clientSecrets、作用域)
.setDataStoreFactory(数据存储工厂)
.setAccessType(“脱机”)
.build();
credential=new AuthorizationCodeInstalledApp(流,new LocalServerReceiver()).Authorization(“用户”);
MyLogger.getLogger().info(credential.getAccessToken()+“”+credential.getRefreshToken()+“”+credential.GetExpirationTimeMillimes()+“”+credential.getExpiresInSeconds());
返回凭证;
}
当应用程序第一次运行时,它会打开一个浏览器页面,供谷歌用户验证并接受条件条款。 然后,凭据被保存到由'DATA\u STORE\u DIR(tipically.credentials/StoredCredential二进制文件)标识的文件夹中

这样,再次运行应用程序可以避免打开浏览器页面:您总是经过身份验证

因此,我希望这个
存储的凭证
有一个过期时间,因此,例如,一个月后,浏览器页面再次打开,并且
存储的凭证
将被覆盖

检查最后一行日志:访问令牌的生命周期只有一个小时,但到期后会自动刷新

我发现的唯一方法是使用
MemoryDataStoreFactory
而不是
FileDataStoreFactory
,但这样每次应用程序运行时都会打开浏览器页面

那么,有没有办法通过
googleapi
获得临时
存储的凭证

我解释了我想要它的原因:应用程序将由不同的用户使用。我希望避免一个用户复制应用程序文件夹并将其交给另一个用户时发生的严重情况。凭证文件夹位于应用程序文件夹中,因此他也将复制
StoredCredential
文件。新用户so将使用具有旧用户身份验证的应用程序

我解释了我想要它的原因:应用程序将由不同的用户使用。我希望避免一个用户复制应用程序文件夹并将其交给另一个用户时发生的严重情况。凭证文件夹位于应用程序文件夹中,因此他也将复制StoredCredential文件。新用户so将使用具有旧用户身份验证的应用程序

这一点非常重要,因为你不想冒险泄露用户信息。然而,你也需要考虑到你不能保护你自己免受愚蠢的用户所做的一切。

由于这个原因,.Net客户端库默认将文件数据存储保存为%appdata%。Java客户机库和.net客户机库的设计非常相似,这就是我可以在这方面提供帮助的原因

您需要做的是将您的凭据存储在主应用程序文件夹之外。我不确定您运行的是哪个系统,但%appdata%适用于windows。这样,如果用户确实复制了目录,他们就不会碰巧复制您的credeintals文件


另一种选择是自己实现数据存储,并可能添加某种检查,以便在创建数据存储时使用机器的mac地址,并且仅在同一台机器上加载数据存储。如果你问我这有点过分。

你应该能够告诉FileDataStoreFactory在哪里存储凭据。是的,我能。这和我问的有什么关系?好的,明白了。我可以把文件夹放在应用程序之外,这是一个我可以避免的选项,我更喜欢一个临时的StoredCredential解决方案。但现在,我选择了你的解决方案。因此,private static final java.io.File DATA_STORE_DIR=new File(System.getProperty(“java.io.tmpdir”)//ResourceLoader.googleCredentials();