【问题标题】:Shopify Authentication Validation with Firebase?使用 Firebase 进行 Shopify 身份验证验证?
【发布时间】:2020-10-09 20:32:56
【问题描述】:

我一直在关注 this 教程,了解如何使用 Node、Nextjs 和 React 构建公共 Shopify 应用程序。

一切进展顺利,但是我现在需要将一些应用数据存储在数据库中。为此,我选择了 Firestore。

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

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

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 应用

server.use(verifyRequest());

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

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 名称是否来自调用它的商店。

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

【问题讨论】:

    标签: javascript node.js firebase shopify next.js


    【解决方案1】:

    考虑到这一点,我可以使用自定义的身份验证方法。

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

    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 是否更改或使用令牌登录用户。

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

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

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

    【讨论】:

    • 你在哪里打电话给admin.initializeApp()
    • @K20GH 很棒,但是我遇到了管理员尚未初始化的问题 - 你在哪里调用/导入?
    猜你喜欢
    • 2017-03-11
    • 1970-01-01
    • 2021-05-26
    • 2017-09-12
    • 2021-07-20
    • 1970-01-01
    • 2017-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多