首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在使用NodeJS (公共应用)时,如何在shopify获取当前商店?

在使用NodeJS (公共应用)时,如何在shopify获取当前商店?
EN

Stack Overflow用户
提问于 2021-09-13 20:16:49
回答 2查看 1.4K关注 0票数 6

我刚接触Shopify App Devlopment,尤其是Shopify API。

我使用Shopify CLI创建了一个正常工作的应用程序,现在想要与API进行通信。

我尝试访问以下端点:https://{my_shop]/admin/api/2021-07/shop.json

我了解到,我需要一些访问令牌和商店名称才能访问此端点。

我在我的私人应用程序部分创建了一个访问令牌。

但我不知道如何获得当前登录的商店。

例如,当在我的前端单击一个按钮时,我想调用我的端点,而我的端点又调用Shopify API端点并检索信息。我怎样才能以正确的方式做到这一点?以及如何获取当前登录的商店?

这是我到目前为止的代码:

代码语言:javascript
复制
import "@babel/polyfill";
import dotenv from "dotenv";
import "isomorphic-fetch";
import createShopifyAuth, { verifyRequest } from "@shopify/koa-shopify-auth";
import Shopify, { ApiVersion } from "@shopify/shopify-api";
import Koa from "koa";
import next from "next";
import Router from "koa-router";
import axios from 'axios';

dotenv.config();
const port = parseInt(process.env.PORT, 10) || 8081;
const dev = process.env.NODE_ENV !== "production";
const app = next({
  dev,
});
const handle = app.getRequestHandler();

Shopify.Context.initialize({
  API_KEY: process.env.SHOPIFY_API_KEY,
  API_SECRET_KEY: process.env.SHOPIFY_API_SECRET,
  SCOPES: process.env.SCOPES.split(","),
  HOST_NAME: process.env.HOST.replace(/https:\/\//, ""),
  API_VERSION: ApiVersion.October20,
  IS_EMBEDDED_APP: true,
  // This should be replaced with your preferred storage strategy
  SESSION_STORAGE: new Shopify.Session.MemorySessionStorage(),
});

// Storing the currently active shops in memory will force them to re-login when your server 
restarts. You should
// persist this object in your app.
const ACTIVE_SHOPIFY_SHOPS = {};

app.prepare().then(async () => {
  const server = new Koa();
  const router = new Router();
  server.keys = [Shopify.Context.API_SECRET_KEY];
  server.use(
    createShopifyAuth({
      async afterAuth(ctx) {
        // Access token and shop available in ctx.state.shopify
        const { shop, accessToken, scope } = ctx.state.shopify;
        const host = ctx.query.host;
        ACTIVE_SHOPIFY_SHOPS[shop] = scope;

        const response = await Shopify.Webhooks.Registry.register({
          shop,
          accessToken,
          path: "/webhooks",
          topic: "APP_UNINSTALLED",
          webhookHandler: async (topic, shop, body) =>
            delete ACTIVE_SHOPIFY_SHOPS[shop],
        });

        if (!response.success) {
          console.log(
            `Failed to register APP_UNINSTALLED webhook: ${response.result}`
          );
        }

        // Redirect to app with shop parameter upon auth
        ctx.redirect(`/?shop=${shop}&host=${host}`);
      },
    })
  );

  router.get("/test2", verifyRequest(), async(ctx, res) => {
    const {shop, accessToken } = ctx.session;
    console.log(shop);
    console.log(accessToken);
  })

  router.get("/test", async (ctx) => {

    const config = {
      headers: {
        'Content-Type': 'application/json',
        'X-Shopify-Access-Token': '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'
      }
    }

    await axios.get('${the_store_name_belongs_here}/admin/api/2021-07/shop.json', config).then(res => {
      ctx.body = res.data;
    });
  });

  const handleRequest = async (ctx) => {
    await handle(ctx.req, ctx.res);
    ctx.respond = false;
    ctx.res.statusCode = 200;
  };

  router.post("/webhooks", async (ctx) => {
    try {
      await Shopify.Webhooks.Registry.process(ctx.req, ctx.res);
      console.log(`Webhook processed, returned status code 200`);
    } catch (error) {
      console.log(`Failed to process webhook: ${error}`);
    }
  });

  router.post(
    "/graphql",
    verifyRequest({ returnHeader: true }),
    async (ctx, next) => {
      await Shopify.Utils.graphqlProxy(ctx.req, ctx.res);
    }
  );

  router.get("(/_next/static/.*)", handleRequest); // Static content is clear
  router.get("/_next/webpack-hmr", handleRequest); // Webpack content is clear
  router.get("(.*)", async (ctx) => {
    const shop = ctx.query.shop;

    // This shop hasn't been seen yet, go through OAuth to create a session
    if (ACTIVE_SHOPIFY_SHOPS[shop] === undefined) {
      ctx.redirect(`/auth?shop=${shop}`);
    } else {
      await handleRequest(ctx);
    }
  });


  server.use(router.allowedMethods());
  server.use(router.routes());
  server.listen(port, () => {
    console.log(`> Ready on http://localhost:${port}`);
  });
});

请查看我的尝试- endpoint /test和endpoint /test2。test2不工作。ctx.session为空。ctx本身为空。为什么?

当我将我的店铺名称硬编码到url中,然后我获得所需的数据时,test1就起作用了。但是我如何在里面放一个shop变量呢?这就是我的奋斗。

EN

回答 2

Stack Overflow用户

发布于 2021-09-24 06:52:29

我遇到了这个问题,并通过将商店作为查询参数传递来解决它。

我使用以下命令调用端点:

代码语言:javascript
复制
axios.get('/test', {
  params: {
    shop: 'fo.myshopify.com'
  }
});

并使用以下命令获取商店:

代码语言:javascript
复制
router.get("/test", async (ctx) => {
  const shop = ctx.query.shop;
  ...
});

当然,您必须知道调用端点的商店。

票数 2
EN

Stack Overflow用户

发布于 2021-09-23 15:09:50

koa-shopify-auth documentation中没有对任何ctx.session的引用。这样如何:

代码语言:javascript
复制
router.get("/test2", verifyRequest(), async(ctx) => {
  const { shop, accessToken } = ctx.state.shopify;
  console.log(shop, accessToken);
})

其他解决方案

您可以在身份验证后存储Cookie

代码语言:javascript
复制
afterAuth(ctx) {
    const { shop, accessToken } = ctx.session;
    ctx.cookies.set("shop", shop, { httpOnly: false, secure: true, sameSite: "none" });
    ctx.redirect("/");
},

然后在以后的请求中阅读它:

代码语言:javascript
复制
router.get("/test2", verifyRequest(), async(ctx) => {
  const shop = ctx.cookies.get("shop");
  console.log(shop);
})
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69168644

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档