使用 Firebase 进行 Shopify 身份验证验证? [英] Shopify Authentication Validation with Firebase?

查看:77
本文介绍了使用 Firebase 进行 Shopify 身份验证验证?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在关注这个 关于如何使用 Node、Nextjs 和 React 构建公共 Shopify 应用的教程.

I've been following this tutorial on how to build a public Shopify app using Node, Nextjs and React.

一切都很顺利,但是我现在需要将我的一些应用程序数据存储在数据库中.为此,我选择了 Firestore.

Everything is going well, however I am now at a point where I need to store some of my app data in a database. For this, I've chosen Firestore.

我所做的是当用户通过他们的商店验证应用程序时,我使用 Next JS 服务器中的 Admin-SDK 将他们的商店和 accessToken 写入文档:

What I am doing is when the user authenticates the app with their store, I use the Admin-SDK within my Next JS server to write their shop and accessToken to a document:

注意:我使用离线"访问模式,因为我需要一个永久访问令牌,以便我的应用程序可以在后台发出 Shopify API 请求.我也知道我应该在存储之前真正加密 accessToken,但是只是试图让逻辑先工作

Note: I'm using the accessMode "offline" as I need a permanent access token so that my app can make Shopify API requests in the background. I also know that I should really encrypt the accessToken before storing it, however just trying to get the logic working first

server.use(
    createShopifyAuth({
        apiKey: SHOPIFY_API_KEY,
        secret: SHOPIFY_API_SECRET_KEY,
        scopes: ['read_products', 'write_products'],
        accessMode: "offline",
        async afterAuth(ctx) {
            const {shop, accessToken} = ctx.session;

            ctx.cookies.set('shopOrigin', shop, {
                httpOnly: false,
                secure: true,
                sameSite: 'none'
            });

            await getSubscriptionUrl(ctx, accessToken, shop);
            await db.collection('shops').doc(shop).set({
                name: shop,
                accessToken
            }, {merge: true});
        },
    }),
);

我还使用 Koa 中间件来验证对我的应用的任何请求,以确保它们来自 Shopify 应用

I am also using the Koa middleware which validates any requests to my app to ensure they are from a Shopify app

server.use(verifyRequest());

我现在想做的是为我的应用添加一种从 Firebase 提取数据的方法.我在 /pages/api/firebase.js 中创建了一个 api 端点,它使用 shopOrigin cookie 来获取商店名称,然后提取该商店的数据.

What I now want to do is to add a way for my app to pull data from Firebase. I've created an api endpoint within /pages/api/firebase.js that uses the shopOrigin cookie to get the store name, and then pull the data for that store.

export default async(req, res) => {
        const shop = req.cookies.shopOrigin;
        const doc = await db.collection('shops').doc(shop).get()
        res.status(200).json({success: true, data: doc.data()});
    }

不过,我面临的问题是,用户可以简单地更改该 cookie 值并为另一家商店提取数据.verifyRequest 函数似乎没有检查调用它的 shopOrigin 名称是否来自调用它的商店.

The problem I'm facing though, is that a user can simply just change that cookies value and pull data for another store. The verifyRequest function doesn't seem to check if the shopOrigin name calling it is from the store that calls it.

有谁知道我如何验证这些请求,以便调用我的 API 的商店只能访问存储数据(通过 Next 服务器上的 admin-sdk)?

Does anyone know how I can validate these requests, so that the store calling my API can only access that stores data (via the admin-sdk on the Next server)?

推荐答案

想到这里,我可以使用自定义身份验证方法.

Thinking about this, I can use a custom authentication method.

在 Next server.js 文件中,以下使用商店名称创建自定义令牌,然后在 cookie 中设置该令牌.例如,它然后在商店集合中创建一个文档,并将文档 ID 作为商店名称.

Within the Next server.js file, the below creates a custom token using the shop name, and then sets that token in a cookie. For the example, it then creates a document in the shops collection with the document ID as the store name.

async afterAuth(ctx) {
    const {shop, accessToken} = ctx.session;

    await getSubscriptionUrl(ctx, accessToken, shop);

    const customToken = await admin.auth().createCustomToken(shop)

    ctx.cookies.set('shopOrigin', shop, {
        httpOnly: false,
        secure: true,
        sameSite: 'none'
    });

    ctx.cookies.set('token', customToken, {
        httpOnly: false,
        secure: true,
        sameSite: 'none'
    });

    await db.collection('shops').doc(shop).set({
        domain: shop,
        token: cryptr.encrypt(accessToken),
    }, {merge: true});
}, 

在 React 应用程序中,初始化您的 Firebase 应用程序实例,然后在 index.js 中侦听 authState 是否更改或使用令牌登录用户.

Within the React app, initialise your Firebase App instance and then within the index.js listen to see if the authState changed or log the user in using the token.

useEffect(() => {
    firebase.auth().onAuthStateChanged(user => {
        if(user) {
            setSignedIn(true)
        } else {
            firebase.auth().signInWithCustomToken(Cookies.get('token'));
        }
    })
},[])

然后在 Firebase 规则中,根据需要设置您的权限

Then in the Firebase rules, set your permissions as required

match /shops/{shop}/{documents=**} {
    allow read, write: if request.auth != null && request.auth.uid == shop
}

这篇关于使用 Firebase 进行 Shopify 身份验证验证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆