【问题标题】:Request origin cannot be verified - Shopify无法验证请求来源 - Shopify
【发布时间】:2017-11-29 12:53:41
【问题描述】:

我正在为 Shopify 开发一个应用程序。目前处于开发阶段。到目前为止,我已经成功地授权应用程序,然后使用嵌入式应用程序 SDK 将其重定向回管理页面。但是,当我返回管理页面时,它给了我一个错误提示 Request origin cannot be verified

控制台显示Failed to load resource: the server responded with a status of 403 (Forbidden) 控制台中的 URL 类似于 https://myshop.myshopify.com/admin/apps/dfdjf4343343434343434bfdf/shopify/shopify/callback?code=ffdfdffd&hmac=fdfdfdfdfdfdfdfdfddfdfdfdfdf&shop=myshop.myshopify.com&state=151193864548800&timestamp=1511938648

fdfdfdfdfdfdfdfdfddfdfdfdfdf 只是我替换的随机字符,而不是哈希。仅供参考 - 我已从图像中删除了应用名称和用户个人资料名称和头像。

【问题讨论】:

    标签: shopify shopify-app


    【解决方案1】:

    发生这种情况是因为,在使用重定向 url 响应时,您无法匹配 cookie 中设置的状态

    const ShopifyToken = require('shopify-token')
    
    const forwardingAddress = process.env.HOST
    
    const shopifyToken = new ShopifyToken({
      sharedSecret: process.env.SHOPIFY_API_SECRET,
      redirectUri: forwardingAddress + '/shopify/callback',
      apiKey: process.env.SHOPIFY_API_KEY
    })
    
    
    const shopify = {
      // use this for authentication
      auth: (req, res, next) => {
        const shop = req.query.shop
        if (!shop) {
          return res.status(400).send('Missing shop parameter. Please add ?shop=your-development-shop.myshopify.com to your request')
        }
        const shopRegex = /^([\w-]+)\.myshopify\.com/i
        const shopName = shopRegex.exec(shop)[1]
        const state = shopifyToken.generateNonce()
        const url = shopifyToken.generateAuthUrl(shopName, scopes, state)
        res.cookie('state', state)
        res.redirect(url)
      },
    
      // use this as your callback function
      authCallback: async (req, res) => {
        const { shop, hmac, code, state } = req.query
        const stateCookie = cookie.parse(req.headers.cookie).state
        if (state !== stateCookie) {
        // you are unable to set proper state ("nonce") in this case, thus you are getting this error
          return res.status(403).send('Request origin cannot be verified')
        }
        if (!shop || !hmac || !code) {
          res.status(400).send('Required parameters missing')
        }
        let hmacVerified = shopifyToken.verifyHmac(req.query)
        console.log(`verifying -> ${hmacVerified}`)
        // DONE: Validate request is from Shopify
        if (!hmacVerified) {
          return res.status(400).send('HMAC validation failed')
        }
        const accessToken = await shopifyToken.getAccessToken(shop, code)
        const shopRequestUrl = 'https://' + shop + '/admin/shop.json'
        const shopRequestHeaders = {
          'X-Shopify-Access-Token': accessToken
        }
        try {
          const shopResponse = await request.get(shopRequestUrl, { headers: shopRequestHeaders })
          res.status(200).end(shopResponse)
        } catch (error) {
          res.status(error.statusCode).send(error.error.error_description)
        }
      }
    }

    【讨论】:

      【解决方案2】:

      虽然很简单,但也要确保协议与您在开始安装应用时输入的内容相匹配。

      如果您不小心将http 用于http://you.ngrok.io/,但您的回调重定向到https(即https://you.ngrok.io/auth/callback),OAuth 握手将失败。

      【讨论】:

        【解决方案3】:

        const express = require('express');
        const router = express.Router();
        const dotenv = require('dotenv').config();
        const cookie = require('cookie');
        const requestPromise = require('request-promise');
        const ShopifyToken = require('shopify-token');
        
        const scopes = "write_products";
        const forwardingAddress = process.env.HOST;
        
        var shopifyToken = new ShopifyToken({
        sharedSecret: process.env.SHOPIFY_API_SECRET,
        redirectUri: forwardingAddress + '/shopify/callback',
        apiKey: process.env.SHOPIFY_API_KEY
        })
        
        router.get('/shopify', (req, res) => {
        const shop = req.query.shop;
        if (!shop) {
            return res.status(400).send('Missing shop parameter. Please add ?shop=your-development-shop.myshopify.com to your request')
        }
        const shopRegex = /^([\w-]+)\.myshopify\.com/i
        const shopName = shopRegex.exec(shop)[1]
        const state = shopifyToken.generateNonce();
        const url = shopifyToken.generateAuthUrl(shopName, scopes, state);
        res.cookie('state', state);
        res.redirect(url);
        });
        
        router.get('/shopify/callback', (req, res) => {
        const { shop, hmac, code, state } = req.query;
        const stateCookie = cookie.parse(req.headers.cookie).state;
        
        if (state !== stateCookie) {
            // you are unable to set proper state ("nonce") in this case, thus you are getting this error
            return res.status(403).send('Request origin cannot be verified')
        }
        if (!shop || !hmac || !code) {
            res.status(400).send('Required parameters missing')
        }
        let hmacVerified = shopifyToken.verifyHmac(req.query)
        console.log(`verifying -> ${hmacVerified}`)
        
        // DONE: Validate request is from Shopify
        if (!hmacVerified) {
            return res.status(400).send('HMAC validation failed')
        }
        const accessToken = shopifyToken.getAccessToken(shop, code);
        const shopRequestUrl = 'https://' + shop + '/admin/products.json'
        const shopRequestHeaders = {
            'X-Shopify-Access-Token': accessToken
        }
        try {
            const shopResponse = requestPromise.get(shopRequestUrl, { headers: shopRequestHeaders })
            res.status(200).send(shopResponse)
        } catch (error) {
            res.status(error.statusCode).send(error.error.error_description)
        }
        
        });
        
        module.exports = router;

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-09-02
          • 2014-03-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-02-13
          相关资源
          最近更新 更多