作为Project Strobe的一部分,谷歌计划将许多Google Drive API的作用域转移到“受限”,这意味着你需要一个独立的安全验证。
在同一篇文章中,他们建议使用Google Picker和drive.file范围来获取每个文件的访问权限。我已经成功地实现了Google Picker API来访问文件和检索文件的元数据。但是,如何实际导入带有此流的文件的内容(例如,实际Google工作表中的数据)?
GOOGLE PICKER包装器
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函数。当文档由应用程序创建时,此函数按预期工作,但当文件由用户在应用程序外部创建时,此函数不起作用。我知道这是谷歌为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}
>发布于 2021-08-18 17:55:24
我最近遇到了这个问题,我需要从谷歌云控制台获取应用程序id,并使用.setAppId(ID_HERE)将其添加到选择器中。这将设置它,以便Google可以设置应用程序和文件链接,然后当您使用该应用程序进行API调用时,它将知道它可以访问该文件。您应该能够在云控制台的同一项目中进行任何API请求设置;对我来说,我在同一项目中启用了Google Drive、Docs和Picker API。我使用选择器允许用户访问应用程序以获取模板文件,然后应用程序可以将该模板复制到用户驱动器,然后使用Doc API将他们的数据注入其中。
您可能还需要设置一个回调函数,以便在用户选择/取消选取器之后执行。例如,我是这样实现的:
var self = this;
var filePickerCallback = (data) => {
if (data[google.picker.Response.ACTION] == google.picker.Action.PICKED) {
var doc = data[google.picker.Response.DOCUMENTS][0];
if (doc["id"] === getTemplateToFindInPicker()){
self.startGoogleDocumentBuild();
} else {
self.showDocsDialog_(ERROR, WRONG FILE SELECTED);
}
}
if(data[google.picker.Response.ACTION] == google.picker.Action.CANCEL){
self.showPickerFlowErrorDialog();
}
}
filePickerCallback.bind(this);
let token = getPickerAccessToken();
var isMCAV = CODE_TO_CHECK_MCAVNESS;
let name = NAME_BASED_ON_CONTEXT;
// let's us choose the query string, what to search based on file name, so its very clear what the user needs to choose
let view = new google.picker.View(google.picker.ViewId.DOCUMENTS).setQuery(name);
var picker = new google.picker.PickerBuilder()
.addView(view)
.setTitle("Please choose: " + name)
.setAppId(getAppIDs())
.setOAuthToken(token)
.setDeveloperKey(getDeveloperKey())
.setCallback(filePickerCallback)
.build();
picker.setVisible(true);发布于 2021-03-03 06:50:32
我认为您需要添加
.setAppId("x")添加到选择器构建器
https://stackoverflow.com/questions/62006021
复制相似问题