如何在 Shopify 嵌入式应用程序(Remix 模板)中进行 Instagram Basic API 身份验证?

问题描述 投票:0回答:1

我正在开发一个 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",
    );
  };

理想情况下,我希望整个流程在用户所在的同一窗口中完成。大家有什么见解吗?

instagram instagram-api shopify-app remix.run
1个回答
0
投票

如果您尝试在弹出窗口中处理身份验证并将数据传递回主应用程序,那么使用 postMessage API 是一种有效的方法。以下是您在用例中实现它的方法:

  1. 打开弹出窗口进行身份验证:首先,打开一个弹出窗口,在其中进行身份验证过程。例如,使用 Instagram,您可以在弹出窗口中将用户引导至 Instagram 登录页面。
  2. 处理重定向并获取访问令牌:用户进行身份验证后,Instagram 将使用访问令牌重定向到指定的 URL。
  3. 兑换长期令牌(如果需要)。
  4. 使用 postMessage 将令牌发送回:在弹出窗口中,使用 postMessage API 将令牌发送回主应用程序窗口。这使您的主应用程序与身份验证流程分开(出于安全原因,请确保其已加密)。

window.opener.postMessage({ token: cryptoToken }, "https://your-main-app-url.com");

  1. 在主窗口中监听消息:在主应用程序中,添加一个事件监听器以接收来自弹出窗口的消息。收到令牌后,您可以对其进行解密(如有必要)并根据需要使用它。

    // 示例:在主窗口接收消息 window.addEventListener("消息", (事件) => { if (event.origin === "https://your-popup-url.com") { const解密Token=解密(event.data.token); // 根据需要使用解密的令牌 } });

© www.soinside.com 2019 - 2024. All rights reserved.