“在此地址上没有页面”。 Shopify嵌入式应用程序错误

发布于 2025-02-14 01:18:24 字数 4990 浏览 1 评论 0原文

当我尝试安装部署的Shopify应用程序时,我会重定向到一个页面,上面写着“此地址上没有页面”。

这很奇怪,因为当我要安装应用程序时,生成的第一个链接是:

https://shopify-app.herokuapp.com/?hmac=d61597ca3ea6ca74b8bd6ea8f8bcc812b4382fad6f15434c0158bc4c3ade519a&host=dXBsaWZ0ZWQtY29tbWVyY2UtZGV2Lm15c2hvcGlmeS5jb20vYWRtaW4&shop=dev.myshopify.com&timestamp=1657326911 

然后将其重定向到错误页面。

当我手动使用此链接时,

https://shopify-app.herokuapp.com/api/auth?shop=dev.myshopify.com

oauth过程无问题。

在我的开发环境中,“安装”链接将我转到:https://test.ngrok.io/api/auth?shop=dev.myshopify.com,除非数据库中有条目对于Active_shopify_shops

当数据库中有条目时,安装链接的格式与我对POR的问题时的格式相同:

https://test.ngrok.io/hmac = 2C3D22200BEE25B5EA3736EBDDDD06494B1EE9A5F2F5FF5FFA310D806417C46417C469F9F9F9F10&host=dxb SAWZ0ZWQTY29TBWVYY2UTZGV2LM15C2HVCGLMES5JB20VYWRTAW4& shop = dev.myshopify.com& timestamp = 1657327896

而且我也将其重定向到“此地址上没有页面”页面。

但是,我的生产数据库是空的。这仅在我的应用的部署的Heroku产品版本上开始发生。

我已经呆了将近8个小时了,我的一生无法弄清楚为什么它不起作用。

我正在使用 shopify cli 来骗这个项目。

知道发生了什么事吗?

这是检查值和重定向验证的值的Catchall路线:

app.use("/*", async (req, res, next) => {
    const shop = req.query.shop;

    const shopValue = await pool.query(`SELECT * FROM shop WHERE shop_url=$1`, [
      shop,
    ]);


    if (shopValue?.rows[0]?.scope) {
      ACTIVE_SHOPIFY_SHOPS[shop] = shopValue.rows[0].scope;
    } else {
      ACTIVE_SHOPIFY_SHOPS[shop] = undefined;
    }

    // Detect whether we need to reinstall the app, any request from Shopify will
    // include a shop in the query parameters.
    if (app.get("active-shopify-shops")[shop] === undefined && shop) {
      res.redirect(`/api/auth?shop=${shop}`);
    } else {
      const fs = await import("fs");
      const fallbackFile = join(
        isProd ? PROD_INDEX_PATH : DEV_INDEX_PATH,
        "index.html"
      );
      res
        .status(200)
        .set("Content-Type", "text/html")
        .send(fs.readFileSync(fallbackFile));
    }
  });

这些是我的auth路线:

export default function applyAuthMiddleware(
  app,
  { billing = { required: false } } = { billing: { required: false } }
) {


  
  
  
  app.get("/api/auth", async (req, res) => {
    console.log("API AUTH");
    if (!req.query.shop) {
      res.status(500);
      return res.send("No shop provided");
    }

    if (!req.signedCookies[app.get("top-level-oauth-cookie")]) {
      return res.redirect(`/api/auth/toplevel?shop=${req.query.shop}`);
    }

    const redirectUrl = await Shopify.Auth.beginAuth(
      req,
      res,
      req.query.shop,
      "/api/auth/callback/offline",
      false
    );

    res.redirect(redirectUrl);
  });

  app.get("/api/auth/toplevel", (req, res) => {
    console.log("AUTH TOPLEVEL");

    res.cookie(app.get("top-level-oauth-cookie"), "1", {
      signed: true,
      httpOnly: true,
      sameSite: "strict",
    });

    res.set("Content-Type", "text/html");

    res.send(
      topLevelAuthRedirect({
        apiKey: Shopify.Context.API_KEY,
        hostName: Shopify.Context.HOST_NAME,
        shop: req.query.shop,
      })
    );
  });

  app.get("/api/auth/callback/offline", async (req, res) => {
    console.log("OFFLINE CALLBACK");

    try {
      const session = await Shopify.Auth.validateAuthCallback(
        req,
        res,
        req.query
      );

      //Save the offline access token
      await pool.query(
        `UPDATE shop SET offline_access_token = $1 WHERE shop_url = $2`,
        [session.accessToken, session.shop]
      );



      //get the online token
      const redirectUrl = await Shopify.Auth.beginAuth(
        req,
        res,
        req.query.shop,
        "/api/auth/callback",
        true
      );

      // Redirect to app with shop parameter upon auth
      res.redirect(redirectUrl);
    } 
  });

  app.get("/api/auth/callback", async (req, res) => {
    console.log("AUTH CALLBACK");

    try {
      const session = await Shopify.Auth.validateAuthCallback(
        req,
        res,
        req.query
      );

      const host = req.query.host;
      app.set(
        "active-shopify-shops",
        Object.assign(app.get("active-shopify-shops"), {
          [session.shop]: session.scope,
        })
      );

      const responses = await Shopify.Webhooks.Registry.registerAll({
        shop: session.shop,
        accessToken: session.accessToken,
      });

      

      Object.entries(responses).map(([topic, response]) => {

        if (!response.success && !gdprTopics.includes(topic)) {
          console.log(
            `Failed to register ${topic} webhook: ${response.result.errors[0].message}`
          );
        }
      });

      // Redirect to app with shop parameter upon auth
      res.redirect(redirectUrl);
    } 
  });
}


When I try and install my deployed Shopify App, I get redirected to a page that says "There’s no page at this address."

It's strange because when I go to install the app, the first link that is generated is:

https://shopify-app.herokuapp.com/?hmac=d61597ca3ea6ca74b8bd6ea8f8bcc812b4382fad6f15434c0158bc4c3ade519a&host=dXBsaWZ0ZWQtY29tbWVyY2UtZGV2Lm15c2hvcGlmeS5jb20vYWRtaW4&shop=dev.myshopify.com×tamp=1657326911 

Which then redirects to the error page.

When I instead manually use this link:

https://shopify-app.herokuapp.com/api/auth?shop=dev.myshopify.com

The Oauth process works without an issue.

In my DEV environment, the "install" link takes me to: https://test.ngrok.io/api/auth?shop=dev.myshopify.com unless there is an entry in the database for ACTIVE_SHOPIFY_SHOPS.

When there is an entry in the database, then the install link is the same format as when I'm having issues with PROD:

https://test.ngrok.io/hmac=2c3d2200bee25b5ea3736ebddd06494b1ee9a5f2f5ffa310d806417c469f9f10&host=dXBsaWZ0ZWQtY29tbWVyY2UtZGV2Lm15c2hvcGlmeS5jb20vYWRtaW4&shop=dev.myshopify.com×tamp=1657327896

And I'm also redirected to the "There’s no page at this address" page.

However, my production database is empty. This only started happening on the deployed Heroku PROD version of my app.

I've been at this for almost 8 hours now and can't for the life of me figure out why it's not working.

I'm using the Shopify CLI to scaffold the project.

Any idea what's going on?

This is the catchall route that checks for a value and redirects to auth:

app.use("/*", async (req, res, next) => {
    const shop = req.query.shop;

    const shopValue = await pool.query(`SELECT * FROM shop WHERE shop_url=$1`, [
      shop,
    ]);


    if (shopValue?.rows[0]?.scope) {
      ACTIVE_SHOPIFY_SHOPS[shop] = shopValue.rows[0].scope;
    } else {
      ACTIVE_SHOPIFY_SHOPS[shop] = undefined;
    }

    // Detect whether we need to reinstall the app, any request from Shopify will
    // include a shop in the query parameters.
    if (app.get("active-shopify-shops")[shop] === undefined && shop) {
      res.redirect(`/api/auth?shop=${shop}`);
    } else {
      const fs = await import("fs");
      const fallbackFile = join(
        isProd ? PROD_INDEX_PATH : DEV_INDEX_PATH,
        "index.html"
      );
      res
        .status(200)
        .set("Content-Type", "text/html")
        .send(fs.readFileSync(fallbackFile));
    }
  });

These are my auth routes:

export default function applyAuthMiddleware(
  app,
  { billing = { required: false } } = { billing: { required: false } }
) {


  
  
  
  app.get("/api/auth", async (req, res) => {
    console.log("API AUTH");
    if (!req.query.shop) {
      res.status(500);
      return res.send("No shop provided");
    }

    if (!req.signedCookies[app.get("top-level-oauth-cookie")]) {
      return res.redirect(`/api/auth/toplevel?shop=${req.query.shop}`);
    }

    const redirectUrl = await Shopify.Auth.beginAuth(
      req,
      res,
      req.query.shop,
      "/api/auth/callback/offline",
      false
    );

    res.redirect(redirectUrl);
  });

  app.get("/api/auth/toplevel", (req, res) => {
    console.log("AUTH TOPLEVEL");

    res.cookie(app.get("top-level-oauth-cookie"), "1", {
      signed: true,
      httpOnly: true,
      sameSite: "strict",
    });

    res.set("Content-Type", "text/html");

    res.send(
      topLevelAuthRedirect({
        apiKey: Shopify.Context.API_KEY,
        hostName: Shopify.Context.HOST_NAME,
        shop: req.query.shop,
      })
    );
  });

  app.get("/api/auth/callback/offline", async (req, res) => {
    console.log("OFFLINE CALLBACK");

    try {
      const session = await Shopify.Auth.validateAuthCallback(
        req,
        res,
        req.query
      );

      //Save the offline access token
      await pool.query(
        `UPDATE shop SET offline_access_token = $1 WHERE shop_url = $2`,
        [session.accessToken, session.shop]
      );



      //get the online token
      const redirectUrl = await Shopify.Auth.beginAuth(
        req,
        res,
        req.query.shop,
        "/api/auth/callback",
        true
      );

      // Redirect to app with shop parameter upon auth
      res.redirect(redirectUrl);
    } 
  });

  app.get("/api/auth/callback", async (req, res) => {
    console.log("AUTH CALLBACK");

    try {
      const session = await Shopify.Auth.validateAuthCallback(
        req,
        res,
        req.query
      );

      const host = req.query.host;
      app.set(
        "active-shopify-shops",
        Object.assign(app.get("active-shopify-shops"), {
          [session.shop]: session.scope,
        })
      );

      const responses = await Shopify.Webhooks.Registry.registerAll({
        shop: session.shop,
        accessToken: session.accessToken,
      });

      

      Object.entries(responses).map(([topic, response]) => {

        if (!response.success && !gdprTopics.includes(topic)) {
          console.log(
            `Failed to register ${topic} webhook: ${response.result.errors[0].message}`
          );
        }
      });

      // Redirect to app with shop parameter upon auth
      res.redirect(redirectUrl);
    } 
  });
}


如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

鲜血染红嫁衣 2025-02-21 01:18:24

这是CLI中的一个错误,该错误已解决在这里

This was a bug in the CLI which was resolved here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文