在生产中安装链接中断- Shopify App.



编辑:我认为问题是app.use(serveStatic(PROD_INDEX_PATH));阻止app.use("/*",中间件运行。我仍在解决方案和任何帮助将不胜感激!

我的Shopify应用程序在部署到Heroku后中断,但只有在点击提供的"安装"时才中断。链接。

例如,当我点击"安装应用程序"时,生成的URL是:https://shopify-app.herokuapp.com/?hmac=d61597ca3ea6ca74b8bd6ea8f8bcc812b4382fad6f15434c0158bc4c3ade519a&host=dXBsaWZ0ZWQtY29tbWVyY2UtZGV2Lm15c2hvcGlmeS5jb20vYWRtaW4&shop=dev.myshopify.com&timestamp=1657326911

它会跳过验证过程并将我带到"此页面不存在"。

所以流程是:"点击安装应用"=比;"这个页面不exist"

但是,如果我手动点击验证链接:https://shopify-app.herokuapp.com/api/auth?shop=dev.myshopify.com,应用程序成功完成验证过程,并且没有任何问题。

我正在使用从Shopify CLI搭建的标准服务器代码。

在生产环境中注释掉这一节允许应用程序部分运行:

if (isProd) {
const compression = await import("compression").then(
({ default: fn }) => fn
);
const serveStatic = await import("serve-static").then(
({ default: fn }) => fn
);
app.use(compression());
app.use(serveStatic(PROD_INDEX_PATH));
}

一旦代码被注释掉,生成的安装链接的格式为:https://shopify-app.herokuapp.com/api/auth?shop=dev.myshopify.com。然而,整个应用程序的功能在点击安装按钮时中断。

新的流程是:"点击安装应用程序"=比;"开始授权流程";=比;接受请求的范围"=比;"应用breaks">

所以本质上,代码片段if(isProd)破坏了安装链接,而删除它会破坏应用程序的其余功能。

更具体地说,是app.use(serveStatic(PROD_INDEX_PATH));代码段。

这个问题真让我挠头。知道是怎么回事吗?

这是我的服务器:
const USE_ONLINE_TOKENS = true;
const TOP_LEVEL_OAUTH_COOKIE = "shopify_top_level_oauth";
// @ts-ignore
const PORT = parseInt(process.env.BACKEND_PORT || process.env.PORT, 10);
const isTest = process.env.NODE_ENV === "test" || !!process.env.VITE_TEST_BUILD;
const versionFilePath = "./version.txt";
let templateVersion = "unknown";
if (fs.existsSync(versionFilePath)) {
templateVersion = fs.readFileSync(versionFilePath, "utf8").trim();
}
// TODO: There should be provided by env vars
const DEV_INDEX_PATH = `${process.cwd()}/frontend/`;
const PROD_INDEX_PATH = `${process.cwd()}/frontend/dist/`;
const DB_PATH = `${process.cwd()}/database.sqlite`;
Shopify.Context.initialize({
// @ts-ignore
API_KEY: process.env.SHOPIFY_API_KEY,
// @ts-ignore
API_SECRET_KEY: process.env.SHOPIFY_API_SECRET,
// @ts-ignore
SCOPES: process.env.SCOPES.split(","),
// @ts-ignore
HOST_NAME: process.env.HOST.replace(/https?:///, ""),
// @ts-ignore
HOST_SCHEME: process.env.HOST.split("://")[0],
API_VERSION: ApiVersion.April22,
IS_EMBEDDED_APP: true,
// This should be replaced with your preferred storage strategy
// SESSION_STORAGE: new Shopify.Session.SQLiteSessionStorage(DB_PATH),
SESSION_STORAGE: new Shopify.Session.CustomSessionStorage(
storeCallback,
// @ts-ignore
loadCallback,
deleteCallback
),
USER_AGENT_PREFIX: `Node App Template/${templateVersion}`,
});

const ACTIVE_SHOPIFY_SHOPS = {};
Shopify.Webhooks.Registry.addHandler("APP_UNINSTALLED", {
path: "/api/webhooks",
webhookHandler: async (topic, shop, body) => {
// @ts-ignore
delete ACTIVE_SHOPIFY_SHOPS[shop],
//Delete unsubscribed shop and clean undefined entries
console.log("APP UNINSTALLED");
await pool.query(
`DELETE FROM shop WHERE shop_url=$1 OR shop_url='undefined' OR shop_url='' OR shop_url IS NULL`,
[shop]
);
},
});

setupGDPRWebHooks("/api/webhooks");
// export for test use only
export async function createServer(
root = process.cwd(),
isProd = process.env.NODE_ENV === "production",
billingSettings = BILLING_SETTINGS
) {
const app = express();
app.set("top-level-oauth-cookie", TOP_LEVEL_OAUTH_COOKIE);
app.set("active-shopify-shops", ACTIVE_SHOPIFY_SHOPS);
app.set("use-online-tokens", USE_ONLINE_TOKENS);
app.use(cookieParser(Shopify.Context.API_SECRET_KEY));

applyAuthMiddleware(app, {
billing: billingSettings,
});
app.post("/api/webhooks", async (req, res) => {
try {
await Shopify.Webhooks.Registry.process(req, res);
console.log(`Webhook processed, returned status code 200`);
} catch (error) {
console.log(`Failed to process webhook: ${error}`);
if (!res.headersSent) {
res.status(500).send(error.message);
}
}
});

app.use(bodyParser.json());
// All endpoints after this point will require an active session
app.use(
"/api/*",
verifyRequest(app, {
// @ts-ignore
billing: billingSettings,
})
);
//app.use("/api/test", test);
app.use("/api/sort-options", sortOptions);
app.use("/api/sort-logic", sortLogic);
app.get("/api/products-count", async (req, res) => {
const session = await Shopify.Utils.loadCurrentSession(req, res, true);
const { Product } = await import(
`@shopify/shopify-api/dist/rest-resources/${Shopify.Context.API_VERSION}/index.js`
);
const countData = await Product.count({ session });
res.status(200).send(countData);
});
app.post("/api/graphql", async (req, res) => {
try {
const response = await Shopify.Utils.graphqlProxy(req, res);
res.status(200).send(response.body);
} catch (error) {
res.status(500).send(error.message);
}
});
app.use(express.json());
app.use((req, res, next) => {
const shop = req.query.shop;
if (Shopify.Context.IS_EMBEDDED_APP && shop) {
res.setHeader(
"Content-Security-Policy",
`frame-ancestors https://${shop} https://admin.shopify.com;`
);
} else {
res.setHeader("Content-Security-Policy", `frame-ancestors 'none';`);
}
next();
});
if (isProd) {
const compression = await import("compression").then(
({ default: fn }) => fn
);
const serveStatic = await import("serve-static").then(
({ default: fn }) => fn
);
app.use(compression());
app.use(serveStatic(PROD_INDEX_PATH));
console.log(`Serving static files from ${PROD_INDEX_PATH}`);
}
app.use("/*", async (req, res, next) => {
const shop = req.query.shop;
console.log("THIS IS THE CATCHALL ROUTE")
// //CHECK TO MAKE SURE SCOPE EXISTS AND ISN'T UNDEFINED, OFFLINE SHOPS?
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.
// @ts-ignore
if (app.get("active-shopify-shops")[shop] === undefined) {
res.redirect(`/api/auth?shop=${shop}`);
} else {
// res.set('X-Shopify-App-Nothing-To-See-Here', '1');
const fs = await import("fs");
console.log(`Serving static files from ${DEV_INDEX_PATH}`);
const fallbackFile = join(
isProd ? PROD_INDEX_PATH : DEV_INDEX_PATH,
"index.html"
);
res
.status(200)
.set("Content-Type", "text/html")
.send(fs.readFileSync(fallbackFile));
}
});
return { app };
}

解决方案正在更改:app.use(serveStatic(PROD_INDEX_PATH));app.use(serveStatic(PROD_INDEX_PATH, { index: false }));

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

相关内容

  • 没有找到相关文章

最新更新