Как исправить ошибку «ActionController::Недействительность аутентификацииtoken» в приложении Shopify с Rails?

#ruby-on-rails #ruby #shopify #shopify-app

Вопрос:

Я запускаю приложение Shopify в режиме разработки с Rails 5.2, размещенным на удаленном сервере ngrok. Когда я пытаюсь опубликовать запись, я получаю ошибку «ActionController::InvalidAuthenticityToken» из Rails. Когда я отключаю токены CSRF, приложение Shopify не работает и показывает ошибку, поэтому я не хочу отключать защиту CSRF, но не знаю, как обойти эту ошибку, не делая этого. Любая помощь была бы очень признательна.

 Rails 5 ActionController::InvalidAuthenticityToken error and ActionController::InvalidAuthenticityToken
 

Ссылаясь на два вышеуказанных вопроса, я добавил следующий код в свой application_controller.rb

 skip_before_action :verify_authenticity_token
protect_from_forgery prepend: true, with: :exception
 

Однако ошибки сохраняются.

Форма, которая приводит к ошибкам после отправки

 <form action="/create_shipment" method="post">
    <%= token_tag %>
      <div class="form-group">
        <label>Username</label>
        <input type="text" class="form-control" name="username" placeholder="e.g. johnsmith">
        
      </div>
      <div class="form-group">
        <label>Secret Key</label>
        <input type="text" class="form-control" name="key" placeholder="e.g. 34ssdfkje3483jkdj83...">
      </div>

      <button type="submit" name="submit" class="btn btn-primary">Submit</button>
</form>
 

маршруты.rb

 Rails.application.routes.draw do
  root :to => 'home#index'
  post '/create_shipment', :to => 'add_user#add_shipment_data'
  get '/products', :to => 'products#index'
  
  mount ShopifyApp::Engine, at: '/'
end
 

добавьте_user_ontroller.rb

 class AddUserController < ApplicationController
  def add_shipment_data
    @user = AddUser.new
    @user.username = params[:username]
    @user.secret_key = params[:key]
    @user.save
  end
end
 

shopify_app.rb

 ShopifyApp.configure do |config|
  config.application_name = "Shipment Method"
  config.old_secret = ""
  config.scope = "write_products, read_products, read_customers, read_orders, write_orders" # Consult this page for more scope options:
                                  # https://help.shopify.com/en/api/getting-started/authentication/oauth/scopes
  config.embedded_app = true
  config.after_authenticate_job = false
  config.api_version = "2021-01"
  config.shop_session_repository = 'Shop'
  config.allow_jwt_authentication = true
  config.allow_cookie_authentication = false

  config.api_key = ENV.fetch('SHOPIFY_API_KEY', SHOPIFY_API_KEY).presence
  config.secret = ENV.fetch('SHOPIFY_API_SECRET', SHOPIFY_API_SECRET).presence
  if defined? Rails::Server
    raise('Missing SHOPIFY_API_KEY. See https://github.com/Shopify/shopify_app#api-keys') unless config.api_key
    raise('Missing SHOPIFY_API_SECRET. See https://github.com/Shopify/shopify_app#api-keys') unless config.secret
  end
end
 

Снимок экрана с Ошибкой

Ответ №1:

Я потратил много часов, пытаясь понять, почему у меня возникли ошибки CSRF с ngrok. Оказывается, что у большинства (всех?) браузеров есть список доменов, в которых они не будут хранить файлы cookie, к которым могут получить доступ поддомены, ngrok.io есть в этом списке. Firefox просто сообщает вам, что домен недействителен, а chrome сообщает, что домен недействителен для хоста, а не истинная причина.

Моим первым решением было сделать Rails.application.config.session_store :cookie_store, …, tld_length: 3

Потом я решился на это

 module ActionDispatch                                                                             
  class Cookies
    class CookieJar                                                                               
      alias handle_options_orig handle_options                                                    
      def handle_options(options)
        if request.host  =~ /ngrok.io/                                                            
          options[:tld_length] = 3                                                                
        end
        handle_options_orig(options)                                                              
      end
    end
  end
end
 

Браузер будет хранить файлы cookie для X.ngrok.io, но не .нгрок.io, который, похоже, используется по умолчанию.

Это было для рельсов 5