#node.js #shopify #koa #shopify-app
Вопрос:
В предыдущей версии я использовал, чтобы получить текущее название магазина примерно так:
router.get("/api/app", async (ctx) => {
let shop = ctx.session.shop;
});
но в новой версии я не могу получить текущее название магазина с помощью ctx.session.shop, я не вижу в журнале никакого объекта с именем name, а также маркера сеанса, я вижу маркер сеанса и название магазина на объекте reffer, но я думаю, что есть другой способ, с помощью которого я могу получить к ним прямой доступ.
итак, как мне узнать текущее название магазина ? вот мой код:
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 session from "koa-session";
import next from "next";
import Router from "koa-router";
import koaBody from "koa-body";
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,
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 = {};
const server = new Koa();
const router = new Router();
router.get("/api/test", async (ctx) => {
return (ctx.body = ctx.session);
});
app.prepare().then(async () => {
server.keys = [Shopify.Context.API_SECRET_KEY];
server.use(
session(
{
sameSite: "none",
secure: true,
},
server
)
);
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}amp;host=${host}`);
},
})
);
const handleRequest = async (ctx) => {
await handle(ctx.req, ctx.res);
ctx.respond = false;
ctx.res.statusCode = 200;
};
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);
}
});
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("(.*)", verifyRequest(), handleRequest); // Everything else must have sessions
server.use(router.allowedMethods());
server.use(router.routes());
server.listen(port, () => {
console.log(`> Ready on http://localhost:${port}`);
});
});
Заранее спасибо.
Ответ №1:
Вот как это сделать внутри вашего server.js файл: Для вашего индексного маршрута, т. е. маршрутизатора.get («/»), установите файл cookie для имени магазина, которое можно получить, как показано ниже. Как только файл cookie будет установлен, когда владельцы магазинов откроют приложение от администратора, теперь, когда вы открываете приложение по своей перенаправляющей ссылке, которая обычно устанавливается на портале партнеров ngrock, название магазина будет автоматически установлено из ранее установленного файла cookie
Полный Код:
router.get("/", async ctx => {
const shop = ctx.query.shop
if (shop) {
console.log("setting cookie");
ctx.cookies.set("shop_name", shop, {
secure: true,
sameSite: 'none',
httpOnly: false
})
}
if (ctx.request.header.cookie) {
var cookies_fetched = parseCookie(ctx.request.header.cookie)
// This shop hasn't been seen yet, go through OAuth to create a session
if (ACTIVE_SHOPIFY_SHOPS[shop] === undefined) {
ctx.redirect(`/auth?shop=${cookies_fetched.shop_name}`)
} else {
await handleRequest(ctx)
}
} else {
if (ACTIVE_SHOPIFY_SHOPS[shop] === undefined) {
ctx.redirect(`/auth?shop=${shop}`)
} else {
await handleRequest(ctx)
}
}
})