我正在使用google drive api创建开源项目但是我有个问题!
如何在nextjs项目上使用next-auth创建gapi-script身份验证?
我可以在gapi-script中使用next-auth进行身份验证,也可以使用googleProvider使用next-auth。
但是如何使用gapi-script npm包与next-auth进行认证?
gapi-script auth
const initClient = () => {
setIsLoadingGoogleDriveApi(true);
gapi.client
.init({
apiKey: API_KEY,
clientId: CLIENT_ID,
discoveryDocs: DISCOVERY_DOCS,
scope: SCOPES,
})
.then(
function () {
// Listen for sign-in state changes.
gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);
// Handle the initial sign-in state.
updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
},
function (error) {}
);
};
*点击查看使用gapi-cript的完整代码
我通过创建一个Gapi上下文并将用户的令牌传递给上下文来解决类似的问题。
我之前在下次授权时抓取了用户令牌并将其存储在我的DB
import React, { useState, createContext, useEffect, useCallback } from "react";
export const GapiClientContext = createContext();
const GAPI_CONFIG = {
apiKey: process.env.NEXT_PUBLIC_FIREBASE_CONFIG_apiKey,
clientId: process.env.GOOGLE_ID,
scope: "https://www.googleapis.com/auth/gmail.send",
discoveryDocs: ["https://www.googleapis.com/discovery/v1/apis/gmail/v1/rest"],
fetch_basic_profile: true,
immediate: true,
plugin_name: "app name",
};
const GapiContextProvider = ({ session, ...props }) => {
const [GapiClient, setGapiClient] = useState(); //{ gapi });
// to test initClient properly, remove access from third party access after each grant:
// https://myaccount.google.com/permissions?continue=https%3A%2F%2Fmyaccount.google.com%2Fsecurity%3Fpli%3D1
// then logout
// to ensure gapi only loads once: https://stackoverflow.com/questions/68985492/how-to-prevent-script-from-loading-multiple-times-with-react
const initClient = useCallback(async () => {
if (window.gapiIsInitialized) return;
console.log("intting gapi");
return gapi.client.init(GAPI_CONFIG).then(
() => {
const access_token =
session.externalAccounts.find((acct) => acct.provider === "gmail")
?.access_token ?? "";
if (access_token === "") return;
gapi.client.setToken({ access_token });
window.gapiIsInitialized = true;
setGmailIsDisabled(false);
return;
},
(e) => {
window.gapiIsLoading = false;
console.info("error init gapi client", e.details);
}
);
}, []);
const setupGapi = useCallback(async () => {
const gapi = await import("gapi-script").then((pack) => pack.gapi);
// https://stackoverflow.com/questions/71040050/why-am-i-getting-syntaxerror-cannot-use-import-statement-outside-a-module
setGapiClient({ gapi });
try {
await gapi.load("client:auth2", initClient);
} catch (e) {
window.gapiIsLoading = false;
console.log("couldnt sign in to gAPI!", e);
}
}, [initClient]);
useEffect(() => {
if (window.gapiIsInitialized || window.gapiIsLoading) return;
window.gapiIsLoading = true;
setupGapi();
}, [initClient, setupGapi]);
return (
<GapiClientContext.Provider
value={{
GapiClient
}}
>
{props.children}
</GapiClientContext.Provider>
);
};
export default GapiContextProvider;
然后在我的应用程序中包装了消费组件一个完整的示例将显示我还跟踪了从上下文提供程序中发送电子邮件的状态……你可以在这里看到:
https://github.com/fotoflo/next-firebase-multi-auth-starter
…我也会在接下来的几天里合并这个上下文
<GapiContextProvider session={session}>
<SendGmailButton emailMessage={emailMessage} />
</GapiContextProvider>
希望这是有帮助的!祝你好运:-)