javascript - 谷歌文件选择器 + drive.file
问题描述
作为 Project Strobe 的一部分,Google 计划将许多 Google Drive API 范围移动到“受限”,这意味着您需要独立的安全验证。
在同一篇文章中,他们建议使用 Google Picker 和 drive.file 范围来获取每个文件的访问权限。我已经成功实现了 Google Picker API 来访问文件并检索文件的元数据。但是我如何通过这个流程实际导入文件的内容(例如,实际 Google 工作表中的数据)?
谷歌选择器包装
import React from "react";
import PropTypes from "prop-types";
import loadScript from "load-script";
const GOOGLE_SDK_URL = "https://apis.google.com/js/api.js";
let scriptLoadingStarted = false;
class GoogleFilePicker extends React.Component {
static propTypes = {
children: PropTypes.node,
clientId: PropTypes.string.isRequired,
developerKey: PropTypes.string,
scope: PropTypes.array,
viewId: PropTypes.string,
authImmediate: PropTypes.bool,
origin: PropTypes.string,
onChange: PropTypes.func,
onAuthenticate: PropTypes.func,
onAuthFailed: PropTypes.func,
createPicker: PropTypes.func,
multiselect: PropTypes.bool,
navHidden: PropTypes.bool,
disabled: PropTypes.bool,
authToken: PropTypes.string,
};
static defaultProps = {
onChange: () => {},
onAuthenticate: () => {},
onAuthFailed: () => {},
scope: ["https://www.googleapis.com/auth/drive.file"],
viewId: "DOCS",
authImmediate: false,
multiselect: false,
navHidden: false,
disabled: false,
authToken: "",
};
constructor(props) {
super(props);
this.onApiLoad = this.onApiLoad.bind(this);
this.onChoose = this.onChoose.bind(this);
}
componentDidMount() {
if (this.isGoogleReady()) {
// google api is already exists
// init immediately
this.onApiLoad();
} else if (!scriptLoadingStarted) {
// load google api and the init
scriptLoadingStarted = true;
loadScript(GOOGLE_SDK_URL, this.onApiLoad);
} else {
// is loading
}
}
isGoogleReady() {
return !!window.gapi;
}
isGoogleAuthReady() {
return !!window.gapi.auth;
}
isGooglePickerReady() {
return !!window.google.picker;
}
onApiLoad() {
window.gapi.load("auth");
window.gapi.load("picker");
}
doAuth(callback) {
window.gapi.auth.authorize(
{
client_id: this.props.clientId,
scope: this.props.scope,
immediate: this.props.authImmediate,
},
callback
);
}
onChoose() {
if (
!this.isGoogleReady() ||
!this.isGoogleAuthReady() ||
!this.isGooglePickerReady() ||
this.props.disabled
) {
return null;
}
// const token = window.gapi.auth.getToken();
// const oauthToken = token && token.access_token;
const oauthToken = this.props.authToken;
if (oauthToken) {
this.createPicker(oauthToken);
} else {
this.doAuth((response) => {
if (response.access_token) {
this.createPicker(response.access_token);
} else {
this.props.onAuthFailed(response);
}
});
}
}
createPicker(oauthToken) {
// this.props.onAuthenticate(oauthToken);
if (this.props.createPicker) {
return this.props.createPicker(window.google, oauthToken);
}
const googleViewId = window.google.picker.ViewId[this.props.viewId];
const view = new window.google.picker.View(googleViewId);
if (this.props.mimeTypes) {
view.setMimeTypes(this.props.mimeTypes.join(","));
}
if (this.props.query) {
view.setQuery(this.props.query);
}
if (!view) {
throw new Error("Can't find view by viewId");
}
const picker = new window.google.picker.PickerBuilder()
.addView(view)
.setOAuthToken(oauthToken)
.setDeveloperKey(this.props.developerKey)
.setCallback(this.props.onChange);
if (this.props.origin) {
picker.setOrigin(this.props.origin);
}
if (this.props.navHidden) {
picker.enableFeature(window.google.picker.Feature.NAV_HIDDEN);
}
if (this.props.multiselect) {
picker.enableFeature(window.google.picker.Feature.MULTISELECT_ENABLED);
}
picker.build().setVisible(true);
}
render() {
console.log(window.gapi);
return (
<div onClick={this.onChoose}>
{this.props.children ? (
this.props.children
) : (
<button>Open google chooser</button>
)}
</div>
);
}
}
export default GoogleFilePicker;
调用包装器
我在下面的代码中调用上面的组件。检索到文档后,我将调用 copyFile 函数。当应用程序创建文档时,此功能按预期工作,但当应用程序外部的用户创建文件时,此功能无法正常工作。我知道 Google 打算将其用于 drive.google.file 范围,但文档暗示使用 Google Picker 应该可以解决此问题。你能澄清一下吗?
<GoogleFilePicker
clientId="CLIENT ID"
developerKey="DEVELOPER KEY"
scope={["https://www.googleapis.com/auth/drive.file"]}
onChange={(data) => {
if (data.docs) {
copyFile(data.docs[0].id, `Template: ${data.docs[0].name}`, "");
}
}}
onAuthenticate={(token) => console.log("oauth token:", token)}
onAuthFailed={(data) => console.log("on auth failed:", data)}
multiselect={true}
navHidden={true}
authImmediate={false}
// mimeTypes={["image/png", "image/jpeg", "image/jpg"]}
viewId={"DOCS"}
authToken={auth.state.user.googleToken}
>
解决方案
推荐阅读
- javascript - 按对象键查询 Firestore
- python - 如何在python中对字典中的列表进行排序?
- android - 在改造中动态传递标题和正文
- python - 如何参考三个点将图像的一部分转移到另一个图像?
- apache-spark - Spark Struct Streaming作业中的多个查询,那么如何缓存数据?
- java - 如何从块中读取文件以上传到Jmeter?
- javascript - Rails adblock JS 文件在生产/开发中表现不同
- html - razor div 使用 css ::after 跳过
- django - {"用户名":["此字段为必填项。"]}
- azure-pipelines - 如何使用 Azure Pipelines yml 创建 GitHub 版本?