前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Google Drive 的信息检索

Google Drive 的信息检索

作者头像
madneal
发布于 2023-09-21 00:27:53
发布于 2023-09-21 00:27:53
28000
代码可运行
举报
文章被收录于专栏:madMenmadMen
运行总次数:0
代码可运行

对于使用 Google 全家桶的公司,Google 文档类的信息泄露时常发生。出现这种情况主要的原因是文档的权限设置问题,用户可能将文档配置为 anyoneCanFind, anyoneWithLink, domainCanFind, domainWithLink,这四种权限都属于比较公开的权限。后两个属于在域内可以查看到文档,一般来说也是不提倡如此设置,尤其是文档中包含敏感信息的。

Auth

如果要使用 Google Drive 的 API,毫无疑问,Google Workspace 的 Auth 则是第一步。对于 Auth,一般可以通过 OAuth 或者 service account 来进行实现,但是 service account 有一个问题是,默认这个 service acount 并没有赋予这个 servive account 这个域内所有资源的访问权限。必须要将这个文档分享给 service account,它才可以访问。这将会影响到对于 domainCanFind 以及 domainWithLink 的文档的搜索。解决办法是需要 delegate domain-wide authority,相当于是对于这个 service account 进行额外的授权,详细的介绍可以参考这个文档[1]。当然,这个授权需要管理员账号来进行,如果申请比较麻烦的话,还可以通过使用 OAuth 的方式来进行认证,这也是 Google Drive API 文档指引中介绍使用的方式。

通过 OAuth 来使用 Drive API 也需要三个步骤:

  1. 1. 启用 API
  2. 2. 配置 OAuth 应用
  3. 3. 生成 Credentials

详细介绍可以参考谷歌的文档[2]介绍,基本上每一步都有详细的介绍。建议可以按照文档的方式来进行操作,OAuth 生成方式会用到一个 credentials.json 文件。如果对 OAuth 流程比较了解的话,应该知道流程中会有一个授权的流程。Go 的官方文档已经提供了一个授权的 demo,通过运行代码可以获取 autorization code,通过 aurhorization code 可以生成 token.json。对于内部应用,生成的 token.json 包含 refresh_token 的话,这个 token 是不会过期的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package main

import (
        "context"
        "encoding/json"
        "fmt"
        "log"
        "net/http"
        "os"

        "golang.org/x/oauth2"
        "golang.org/x/oauth2/google"
        "google.golang.org/api/drive/v3"
        "google.golang.org/api/option"
)

// Retrieve a token, saves the token, then returns the generated client.
func getClient(config *oauth2.Config) *http.Client {
        // The file token.json stores the user's access and refresh tokens, and is
        // created automatically when the authorization flow completes for the first
        // time.
        tokFile := "token.json"
        tok, err := tokenFromFile(tokFile)
        if err != nil {
                tok = getTokenFromWeb(config)
                saveToken(tokFile, tok)
        }
        return config.Client(context.Background(), tok)
}

// Request a token from the web, then returns the retrieved token.
func getTokenFromWeb(config *oauth2.Config) *oauth2.Token {
        authURL := config.AuthCodeURL("state-token", oauth2.AccessTypeOffline)
        fmt.Printf("Go to the following link in your browser then type the "+
                "authorization code: \n%v\n", authURL)

        var authCode string
        if _, err := fmt.Scan(&authCode); err != nil {
                log.Fatalf("Unable to read authorization code %v", err)
        }

        tok, err := config.Exchange(context.TODO(), authCode)
        if err != nil {
                log.Fatalf("Unable to retrieve token from web %v", err)
        }
        return tok
}

// Retrieves a token from a local file.
func tokenFromFile(file string) (*oauth2.Token, error) {
        f, err := os.Open(file)
        if err != nil {
                return nil, err
        }
        defer f.Close()
        tok := &oauth2.Token{}
        err = json.NewDecoder(f).Decode(tok)
        return tok, err
}

// Saves a token to a file path.
func saveToken(path string, token *oauth2.Token) {
        fmt.Printf("Saving credential file to: %s\n", path)
        f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
        if err != nil {
                log.Fatalf("Unable to cache oauth token: %v", err)
        }
        defer f.Close()
        json.NewEncoder(f).Encode(token)
}

func main() {
        ctx := context.Background()
        b, err := os.ReadFile("credentials.json")
        if err != nil {
                log.Fatalf("Unable to read client secret file: %v", err)
        }

        // If modifying these scopes, delete your previously saved token.json.
        config, err := google.ConfigFromJSON(b, drive.DriveMetadataReadonlyScope)
        if err != nil {
                log.Fatalf("Unable to parse client secret file to config: %v", err)
        }
        client := getClient(config)

        srv, err := drive.NewService(ctx, option.WithHTTPClient(client))
        if err != nil {
                log.Fatalf("Unable to retrieve Drive client: %v", err)
        }

        r, err := srv.Files.List().PageSize(10).
                Fields("nextPageToken, files(id, name)").Do()
        if err != nil {
                log.Fatalf("Unable to retrieve files: %v", err)
        }
        fmt.Println("Files:")
        if len(r.Files) == 0 {
                fmt.Println("No files found.")
        } else {
                for _, i := range r.Files {
                        fmt.Printf("%s (%s)\n", i.Name, i.Id)
                }
        }
}

完整的项目代码可以参考 GitHub 上面的代码仓库[3]。上面有完整的代码, go run quickstart.go 即可运行获取 token 文件。

检索

在我们获取 credentials.json 以及 token.json 文件之后,就已经能够完成 API 的鉴权。Files.List API 是进行文件检索的核心 API。完整的搜索语法可以参考 Google 的文档[4]。

image.png

另外一个重要的实现就是 API 的翻页功能。不过 API 的翻页和其它普通的翻页不太一样,因为它不是使用普通的 page_no 来进行翻页。它是通过 pageToken 来进行翻页,而 pageToken 是随机字符串,而不是普通的数字。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func getResults(keyword, query string) {
    pageToken := ""
    results := make([]file.File, 0)
    for {
        r, err := scanner.service.Files.List().PageSize(10).Fields("nextPageToken,files(*)").
            Q(query).Corpus("domain").
            PageToken(pageToken).Do()
        if err != nil {
            
        }
        results = append(results, r.file())
        if r.NextPageToken == "" {
            break
        }
        pageToken = r.NextPageToken
    }
    return results
}

通过 Fields 可以指定响应里面返回的字段,通过 Corpus 可以限定域内资源的搜索。至此,基本上可以实现通过关键词实现对 Google Drive 信息的检索。虽然 Google Drive 支持关键词的全文搜索,但是搜索结果不支持展示匹配的上下文,这是唯一比较欠缺的地方。

引用链接

[1] 文档: https://developers.google.com/cloud-search/docs/guides/delegation [2] 文档: https://developers.google.com/drive/api/quickstart/go [3] 代码仓库: https://github.com/googleworkspace/go-samples/blob/main/drive/quickstart/quickstart.go [4] 文档: https://developers.google.com/drive/api/guides/ref-search-terms

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-09-17 10:21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 madMen 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
grpc-go之身份验证(二)
在gRPC中,身份验证被抽象为了credentials.PerRPCCredentials接口:
Johns
2022/09/28
1.5K0
grpc-go之超时与重试(三)
go里面一般会使用Context进行超时控制以及参数传递, 其中超时控制可以使用context.WithDeadline()或者context.WithTimeout()实现, 二者实现效果是一致的.
Johns
2022/09/28
3K1
grpc-go之负载均衡(七)
gRPC 中的负载平衡基于每个调用而不是每个连接发生。即使所有请求都来自单个客户端,我们仍然希望它们在所有服务器之间进行负载平衡。
Johns
2022/10/12
1.1K0
中文全文检索技术路线(elasticsearch全文检索、中文分词ik、tika解析文档)
代码在开源仓库3xxxhttps://github.com/3xxx/engineercms
hotqin888
2021/12/06
9740
中文全文检索技术路线(elasticsearch全文检索、中文分词ik、tika解析文档)
使用 AI 辅助开发一个开源 IP 信息查询工具:二
在上一篇文章《使用 AI 辅助开发一个开源 IP 信息查询工具:一[1]》中,我们已经将初版代码推送到了开源项目 soulteary/ip-helper[2]。
soulteary
2024/12/23
1350
使用 AI 辅助开发一个开源 IP 信息查询工具:二
rclone挂载Google Drive
元旦在土区成功购买Google one 2T之后,就着手开始用rclone挂载Google Drive
行 者
2023/10/20
9350
Go + gRPC-Gateway(V2) 构建微服务实战系列,小程序登录鉴权服务:第一篇(内附开发 demo)
小程序可以通过微信官方提供的登录能力方便地获取微信提供的用户身份标识,快速建立小程序内的用户体系。
为少
2021/05/27
1.3K0
Go + gRPC-Gateway(V2) 构建微服务实战系列,小程序登录鉴权服务:第一篇(内附开发 demo)
如何在 Python 测试脚本中访问需要登录的 GAE 服务
我有一个 GAE restful 服务,需要使用管理员帐户登录。而我正在用 Python 编写一个自动化脚本来测试这个服务。这个脚本只是执行一个 HTTP POST,然后检查返回的响应。对我来说困难的部分是如何将测试脚本验证为管理员用户。
用户11021319
2024/04/16
3020
如何在 Python 测试脚本中访问需要登录的 GAE 服务
Go实战--golang中使用RethinkDB(gorethink/gorethink.v3)
生命不止,继续go go go !!! 关于golang中操作数据库,曾经介绍了不少: Go实战–go语言操作sqlite数据库(The way to go) Go实战–go语言操作MySQL数据库
程序员的酒和故事
2018/03/12
1.8K0
Go实战--golang中使用RethinkDB(gorethink/gorethink.v3)
golang实现http2.0服务端,客户端完整案例
为了学习golang的client源码执行流程,所以笔者通过golang实现http2的服务端和客户端,然后通过单步调试学习源码。下面我们看下整个golang实现http2的服务步骤。
公众号-利志分享
2022/04/25
5.2K0
elasticsearch学习二:导入数据
本文为仙士可原创文章,转载无需和我联系,但请注明来自仙士可博客www.php20.cn
仙士可
2022/06/12
7720
几种封装 HTTP Authorization 的分装方式
其实, 这种就是 HTTP Authentication[1] 中的 Basic 模式(Schema)
老麦
2024/01/29
3270
几种封装 HTTP Authorization 的分装方式
[原创]Google SEO教程之Google Indexing API第一时间抓取新页面
1 Google SEO教程之Google Indexing API第一时间抓取新页面
极客中心
2021/01/21
3.2K0
[原创]Google SEO教程之Google Indexing API第一时间抓取新页面
使用 AI 辅助开发一个开源 IP 信息查询工具:一
在写代码时,总是会遇到一些有趣的机缘巧合。前几天,我在翻看自己之前的开源项目时,又看到了 DDNS 相关的讨论。虽然在 2021 年我写过两篇相对详细的教程:《使用 Nginx 提供 DDNS 服务(前篇)[1]》和《使用 Nginx 提供 DDNS 服务(中篇)[2]》,但总觉得还可以做得更好。
soulteary
2024/12/23
1510
使用 AI 辅助开发一个开源 IP 信息查询工具:一
GoIndex&GdIndex 两个无需服务器的Google Drive目录索引程序
首先肯定是需要一个谷歌网盘的,这里直接使用goindex提供的快速部署方法,由于使用的是rclone的google api,高峰期难免会出现点问题,后面也会说下使用自己的api部署方法。
西方记者
2022/02/25
2.3K0
GoIndex&GdIndex 两个无需服务器的Google Drive目录索引程序
使用 AI 辅助开发一个开源 IP 信息查询工具:一
在写代码时,总是会遇到一些有趣的机缘巧合。前几天,我在翻看自己之前的开源项目时,又看到了 DDNS 相关的讨论。虽然在 2021 年我写过两篇相对详细的教程:《使用 Nginx 提供 DDNS 服务(前篇)》和《使用 Nginx 提供 DDNS 服务(中篇)》,但总觉得还可以做得更好。
soulteary
2024/12/22
1050
使用 AI 辅助开发一个开源 IP 信息查询工具:一
k8s first commit 源码分析之 Cloudcfg
cloudcfg 可以看做是 kubectl 的前身,负责与 API server 的交互,只存在于上古时代的 k8s 中,我们现在接触到的都是叫做 kubectl 的命令行工具了。该组件做的事情非常简单,就是将用户的命令行操作转化为对 API server 的 HTTP 请求。
菜菜cc
2022/11/15
2740
go grpc 初步笔记
像许多RPC系统一样,gRPC基于定义服务的思想,指定可以使用其参数和返回类型远程调用的方法。
solate
2019/07/22
6430
从gRPC安全设计理解双向证书方案
网络安全领域在攻和防对抗规模群体已经成熟,但是两端从业者对于安全原理掌握程度参差不齐,中间鸿沟般的差距构成了漏洞研究领域的主战场。笔者“三省吾身”,在工作中会犯错误把一些加密、认证、鉴权的概念和实现方案搞混,尤其是加解密涉及算法和公私钥机制的概念不深入细节。
安全乐观主义
2020/11/09
2.7K0
从gRPC安全设计理解双向证书方案
最佳实践|用腾讯云智能文字识别实现网约车信息管理
据网约车监管信息交互平台统计,截至2022年7月31日,全国共有279家网约车平台公司取得网约车平台经营许可,各地共发放网约车驾驶员证460.0万本、车辆运输证188.2万本,至7月份共收到订单信息6.95亿单。网约车司机的身份、驾驶证、行驶证、车辆信息的收集和管理是一项非常艰巨的任务,安全合规地收集管理网约车的信息可以有效的保障乘客的安全,加强对驾驶员的审核,提升出行的安全。
腾讯云AI
2023/04/17
3.5K0
最佳实践|用腾讯云智能文字识别实现网约车信息管理
推荐阅读
相关推荐
grpc-go之身份验证(二)
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档