我正在开发一个 Shopify (Remix) 应用程序,它使用 Instagram Basic API 从用户帐户中获取 Reels。 Instagram 会提示用户登录以获取访问令牌。用户登录后,Instagram 将用户重定向到我提供的 URL (redirect_url)。
但是问题是,我的应用程序是嵌入的,所以假设用户正在 https://shopname.myshopify.com/app/appname 使用我的应用程序,Instagram 将用户重定向到我的应用程序的域(我已提供) ,这种方法可行,但它会立即让用户死记硬背地/登录(因为该应用程序未在新窗口中进行身份验证)
我在我的 remix 应用程序 instagram.$.tsx 中创建了这条路线来处理流程:
import type { LoaderFunctionArgs } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
import { CLIENT_ID } from "~/utils.ts/instagram/creds.common";
import { CLIENT_SECRET } from "~/utils.ts/instagram/creds.server";
export const loader = async ({ request }: LoaderFunctionArgs) => {
const url = new URL(request.url);
const code = url.searchParams.get("code");
// If code is present, then we need to exchange it for an access token
if (code) {
const response = await fetch(
"https://api.instagram.com/oauth/access_token",
{
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams({
code,
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
grant_type: "authorization_code",
redirect_uri: `${process.env.SHOPIFY_APP_URL}/instagram`,
}),
},
);
const data = await response.json();
const accessToken = data?.access_token;
if (accessToken) {
const response = await fetch(
`https://graph.instagram.com/me/media?fields=id,username,media_type,media_url,thumbnail_url&access_token=${accessToken}`,
);
const data = await response.json();
console.log("Media Data:", data);
return data?.data;
}
}
return [];
};
type InstagramMedia = {
id: string;
media_url: string;
media_type: "IMAGE" | "VIDEO";
};
const renderMedia = (media: InstagramMedia) => {
switch (media.media_type) {
case "IMAGE":
return (
<img
key={media.id}
src={media.media_url}
alt="Instagram Media"
style={{ width: "100%" }}
/>
);
case "VIDEO":
return (
<video muted key={media.id} style={{ width: "100%" }}>
<source src={media.media_url} type="video/mp4" />
</video>
);
}
};
export default function Instagram() {
const data = useLoaderData<typeof loader>();
return (
<div>
<h1>Instagram Catalogue</h1>
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr" }}>
{data.map(renderMedia)}
</div>
</div>
);
}
这就是用户重定向到 Instagram 身份验证的方式:
const handleInstagramImportClick = () => {
window.open(
`https://api.instagram.com/oauth/authorize?client_id=${CLIENT_ID}&redirect_uri=${redirectUrl}&scope=${SCOPE}&response_type=code`,
"_blank",
);
};
理想情况下,我希望整个流程在用户所在的同一窗口中完成。大家有什么见解吗?
如果您尝试在弹出窗口中处理身份验证并将数据传递回主应用程序,那么使用 postMessage API 是一种有效的方法。以下是您在用例中实现它的方法:
window.opener.postMessage({ token: cryptoToken }, "https://your-main-app-url.com");
在主窗口中监听消息:在主应用程序中,添加一个事件监听器以接收来自弹出窗口的消息。收到令牌后,您可以对其进行解密(如有必要)并根据需要使用它。
// 示例:在主窗口接收消息 window.addEventListener("消息", (事件) => { if (event.origin === "https://your-popup-url.com") { const解密Token=解密(event.data.token); // 根据需要使用解密的令牌 } });