我一直在按照本教程学习如何使用Node,Nextjs和React构建公共Shopify应用程序。
一切进展顺利,但是现在我需要将一些应用程序数据存储在数据库中。为此,我选择了Firestore。
我正在做的是,当用户通过商店对其应用程序进行身份验证时,我在Next JS服务器中使用Admin-SDK将其shop和accessToken写入文档:
注意:我正在使用accessMode“ offline”,因为我需要一个永久访问令牌,以便我的应用可以在后台发出Shopify API请求。我也知道我应该在存储访问令牌之前先对其进行加密,但是只是想让逻辑先工作
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提取数据的方法。我已经在其中创建了一个api端点,/pages/api/firebase.js
该端点使用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)?
考虑到这一点,我可以使用自定义身份验证方法。
在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 App实例,然后在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
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句