无需身份验证令牌即可访问 Google 电子表格 API

Posted

技术标签:

【中文标题】无需身份验证令牌即可访问 Google 电子表格 API【英文标题】:Access Google spreadsheet API without auth token 【发布时间】:2017-10-18 02:47:21 【问题描述】:

我已经创建了 Google 电子表格,并授予了所有人的编辑权限(即使没有登录也可以编辑)。

这里是link。我想用 Google 电子表格 API 更新这张表。但我收到错误。我的要求是通过 API 更新工作表,即使没有访问凭据。

【问题讨论】:

您找到解决方案了吗?似乎即使使用“任何人都可以编辑模式”,我们也只能读取数据而不能更改或添加一些 【参考方案1】:

可以在没有OAuthAPI Keys 的情况下写入电子表格。您需要使用Service Account Keys

这是我为我的 Node.js 环境所做的。

    从https://console.cloud.google.com/apis/credentials 获取服务帐户密钥(您也可以在此处限制允许此密钥执行的操作)
      创建时,请确保单击Furnish a new private key 在询问您如何下载密钥时选择JSON
    您刚刚生成的service account key 包含一个client_email
      转到您的 Google 电子表格并允许此 client_email 对此文档具有写入权限

    使用以下代码进行身份验证

    let jwtClient = new google.auth.JWT(client_email, null, private_key, [ "https://www.googleapis.com/auth/spreadsheets", ]); //authenticate request jwtClient.authorize(function(err, tokens) // at this point the authentication is done you can now use `jwtClient` // to read or write to the spreadsheet );

client_emailprivate_keyservice account key 的一部分

可以在此处找到更详细的说明。 http://isd-soft.com/tech_blog/accessing-google-apis-using-service-account-node-js/ 另外,所有的功劳都归于这个页面。

【讨论】:

NVM(供未来的观众使用)只是没有调用 require("googleapis").google (github.com/googleapis/google-api-nodejs-client#getting-started) 我们如何通过 Java 实现这一点?【参考方案2】:

你需要是authorized to make such requests

您的应用程序发送到 Google Sheets API 的每个请求都需要 向 Google 识别您的申请。有两种鉴别方法 您的应用程序:使用 OAuth 2.0 令牌(它还授权 请求)和/或使用应用程序的 API 密钥。这是如何 确定使用哪些选项:

如果请求需要授权(例如请求 个人的私人数据),则应用程序必须提供 OAuth 2.0 令牌与请求。应用程序也可以提供 API 密钥,但不是必须的。如果请求不需要 授权(例如对公共数据的请求),然后 应用程序必须提供 API 密钥或 OAuth 2.0 令牌,或者 两者都 - 任何对您来说最方便的选项。

就是这样。没有绕过授权。

【讨论】:

我已经创建了 API 密钥,并在邮递员标头密钥中添加了该密钥:授权值:key=。但它仍然无法正常工作。 @Nageswaran 您必须在查询字符串中传递它,而不是标题。见developers.google.com/sheets/api/guides/authorizing#APIKey 相同的键适用于 GET 请求,但不适用于 PUT 请求:/。我错过了什么吗? 这里有同样的问题。上述限制仅涵盖读取数据而不写入对公众开放的具有完全编辑权限的工作表。希望他们对此更清楚。写入完全开放的表单有很好的用例。【参考方案3】:

终于挖得够深,找到了答案。任何类型的写作,甚至是可公开编辑的工作表都需要 OAuth 流程:

https://issuetracker.google.com/issues/36755576#comment3

【讨论】:

【参考方案4】:

Jürgen Brandstetter 的上述回答是完全正确的。使用 Postman,我在不使用 OAuth 令牌的情况下取得了成功(我需要我的个人 API 密钥和服务帐户) - 我已经写入了一个新工作表(实际上我通过两个步骤进行了 batchUpdate 操作,首先创建一个新工作表和然后粘贴数据就可以了)。我按照here 的说明创建了一个服务帐户,下载了凭证 JSON 并使用它创建并签署了一个 JWT 字符串,该字符串后来用作 Bearer。

这里是获取 JWT 字符串的 Java 代码:

    private static String getSignedJWT() throws IOException 
        InputStream in = YourClass.class.getResourceAsStream("/downloaded-service-account-creds.json");
        if (in == null) 
            throw new FileNotFoundException("Resource not found");
        
        ServiceAccountCredentials serviceAccountCredentials = ServiceAccountCredentials.fromStream(in);
        GoogleCredentials googleCredentials = serviceAccountCredentials
                .createScoped(Collections.singletonList(SheetsScopes.SPREADSHEETS));

        PrivateKey privateKey = serviceAccountCredentials.getPrivateKey();
        String privateKeyId = serviceAccountCredentials.getPrivateKeyId();

        long now = System.currentTimeMillis();

        Algorithm algorithm = Algorithm.RSA256(null, (RSAPrivateKey)privateKey);
        String signedJwt = JWT.create()
                .withKeyId(privateKeyId)
                .withIssuer(serviceAccountCredentials.getClientEmail())
                .withSubject(serviceAccountCredentials.getClientEmail())
                .withAudience("https://sheets.googleapis.com/")
                .withIssuedAt(new Date(now))
                .withExpiresAt(new Date(now + 3600 * 1000L))
                .sign(algorithm);

        return signedJwt;
    

需要的依赖项:com.auth0:java-jwt 和 com.google.auth:google-auth-library-oauth2-http。

这是使用上面生成的 JWT 字符串的 curl:

curl --location --request POST 'https://sheets.googleapis.com/v4/spreadsheets/YOUR_SHEET_ID:batchUpdate?key=ANY_PERSONAL_API_KEY' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_JWT_STRING' \
--data-raw '
    "requests": [
        
            "addSheet": 
                "properties": 
                    "title": "newPred",
                    "sheetId": 0
                
            
        ,
        
            "pasteData": 
                "coordinate": 
                    "columnIndex": 0,
                    "rowIndex": 0,
                    "sheetId": 0
                ,
                "delimiter": "\t",
                "data": "col1\tcol2\nPeter\t25",
                "type": "PASTE_NORMAL"
            
        
    ]
'

【讨论】:

以上是关于无需身份验证令牌即可访问 Google 电子表格 API的主要内容,如果未能解决你的问题,请参考以下文章

Django REST to React - 无需密码即可获取社交身份验证令牌

Elasticsearch:无需基本身份验证即可创建用于访问的不记名令牌

使用 GitLab 令牌无需身份验证即可克隆

使用 Firebase 身份验证进行身份验证后检索 Google 访问令牌

Google 登录 - 访问令牌、身份验证令牌和 JWT ID 令牌之间的区别

无需 oAuth 即可连接到非 Google 服务的 Gmail 插件