#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