I have a react app that allows user to pipe in a particular Google Doc that we then analyze the content of. For step 1, picking the document, I'm using this nifty npm package, which also returns to me an "OAuth token", which I presume to be an access_token
I can use to make API calls. I set the returned token and the data returned by the Picker API as state variables in my component, as seen below
<GooglePicker clientId={process.env.REACT_APP_GOOGLE_CLIENT_ID}
developerKey={process.env.REACT_APP_GOOGLE_API_KEY}
scope={SCOPES}
onAuthenticate={(token: any) => {
setGoogleToken(token)
}}
onChange={(data: any) => {
setGoogleData(data);
nextOnboardingStage();
}}
onAuthFailed={(data: any) => console.log('on auth failed:', data)}
multiselect={true}
navHidden={true}
authImmediate={false}
mimeTypes={['application/vnd.google-apps.document']}
viewId={'DOCS'}>
<MyCustomButton />
</GooglePicker>
I then try to call the Drive API export function to download said file in this function
const downloadGoogleDoc = async (authToken: string, fileID: string) => {
const res = await axios.get(`https://www.googleapis.com/drive/v3/files/${fileID}/export`, {
headers: {
'Authorization': `token ${authToken}`
}
});
console.log(res);
};
However, I'm getting a 401 error when doing this. Can someone point out where I'm losing the auth? Thanks so much
Edit My entire component is below
const SCOPES = ['https://www.googleapis.com/auth/drive.readonly'];
const Project: React.FC<ProjectInput> = () => {
const [googleToken, setGoogleToken] = useState<string>();
const [googleData, setGoogleData] = useState<any>({});
const [documentData, setDocumentData] = useState();
const downloadGoogleDoc = async (authToken: string, fileID: string) => {
try {
const res = await axios.get(`https://www.googleapis.com/drive/v3/files/${fileID}/export`, {
headers: {
'Authorization': `Bearer ${authToken}`
}
});
console.log(res);
} catch(e) {
console.log(e);
console.log(e.message);
}
};
console.log(googleToken);
console.log(googleData);
const MyCustomButton = () => {
return (
<button className="mx-8 my-2 p-2 rounded bg-blue-500 text-white">
Select From Google Drive
</button>
)
}
if (googleToken && googleData.docs) {
downloadGoogleDoc(googleToken, googleData.docs[0].id);
}
return (
<div className={`ml-${sideBarWidth}`}>
<FadeIn>
<div className="flex flex-col min-h-screen bg-gray-500 py-6 justify-center sm:py-12">
<div className="py-3 sm:max-w-xl sm:mx-auto">
<div className="bg-white min-w-1xl flex flex-col rounded-xl shadow-lg">
<div className="flex">
<div>
<div>
<div className="px-8 py-5">
<h2 className="text-gray-800 text-3xl font-semibold">Great! Select the document you'd like us to scan</h2>
</div>
</div>
<GooglePicker clientId={process.env.REACT_APP_GOOGLE_CLIENT_ID}
developerKey={process.env.REACT_APP_GOOGLE_API_KEY}
scope={SCOPES}
onAuthenticate={(token: any) => {
setGoogleToken(token)
}}
onChange={(data: any) => {
setGoogleData(data);
nextOnboardingStage();
}}
onAuthFailed={(data: any) => console.log('on auth failed:', data)}
multiselect={true}
navHidden={true}
authImmediate={false}
mimeTypes={['application/vnd.google-apps.document']}
viewId={'DOCS'}>
<MyCustomButton />
</GooglePicker>
</div>
</div>
</div>
</div>
</div>
</FadeIn>
</div>
);
};
export default Project;
EDIT
As @Tanaike said, I needed to include MimeType in my request, working function is below
const downloadGoogleDoc = async (authToken: string, fileID: string) => {
try {
const params = new URLSearchParams([['mimeType', 'text/html']]);
const res = await axios.get(`https://www.googleapis.com/drive/v3/files/${fileID}/export`, {
params,
headers: {
'Authorization': `Bearer ${authToken}`
}
});
console.log(res);
} catch(e) {
console.log(e);
console.log(e.message);
}
};
question from:
https://stackoverflow.com/questions/66057253/error-401-when-trying-to-download-a-file-after-using-google-picker-api 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…