如何将 CSRF 令牌真实性从我拥有的 php 应用程序发送到我拥有的 rails 应用程序?
How do I send CSRF token authenticity from a php app that I own to a rails app that I own?
我是 sugarCRM 实例的管理员,我在 heroku 上有一个 rails 应用程序。如果在 sugarCRM 中添加联系人,我希望能够自动将联系人添加到 rails 应用程序。我在我的 sugarCRM 中写了一个 before_save logic_hook:
function pushConts($bean, $event, $arguments)
{
$r = new HttpRequest('http://localhost:3000/contacts/', HttpRequest::METH_POST);
$r->addPostFields(array('first_name' => $bean->first_name, 'last_name' => $bean->last_name, 'phone' => $bean->phone_mobile,'email' => $bean->email1, ));
//$r->addHeaders(array('X-CSRF-Token'=> 'testing-csrf-token');
try
{
echo $r->send()->getBody();
} catch(HttpException $ex){
SugarApplication::appendErrorMessage("<span style='color: red; font-size: 1.8em;'>Could Not Save Contact: Rails app is down.</span>");
$queryParams = array('module' => 'Contacts', 'action' => 'ListView');
SugarApplication::redirect('index.php?' . http_build_query($queryParams));
}
当我尝试按原样发送时,rails 应用程序的控制台输出是:
Started POST "/contacts/" for 127.0.0.1 at 2015-06-18 15:30:14 -0500
Processing by ContactsController#create as */*
Parameters: {"first_name"=>"contact", "last_name"=>"one", "phone"=>"(555) 555-5555", "email"=>"phone.support@example.us"}
Can't verify CSRF token authenticity
Completed 422 Unprocessable Entity in 1ms
ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
actionpack (4.2.0) lib/action_controller/metal/request_forgery_protection.rb:181:in `handle_unverified_request'
actionpack (4.2.0) lib/action_controller/metal/request_forgery_protection.rb:209:in `handle_unverified_request'
devise (3.4.1) lib/devise/controllers/helpers.rb:251:in `handle_unverified_request'
<stack trace continues>
我知道逻辑挂钩本身有效,因为我尝试将 skip_before_filter :verify_authenticity_token
添加到我的联系人控制器,然后它按预期工作,但出于安全原因,这不是一个可行的解决方案。
如您所见,注释掉了,我尝试用 headers 发送 X-CSRF-Token
,但这也没有用。
我可以向这个逻辑挂钩或我的 rails 应用程序本身(或两者)添加什么,以便我可以将 Http 请求从我的 sugarCRM 发送到我的 rails 应用程序而不会妥协(也多)安全?
Rails CSRF 系统并非真正旨在跨域或跨服务器工作。 It leverages synchronizer tokens (cryptographically random tokens) which are bound to the user's session.
由于 Rails 和 SugarCRM 不共享用户会话,因此 Rails 无法验证来自 SugarCRM 的 CSRF 令牌。
你最好的选择是关闭它以进行 skip_before_filter, only: [:create]
的操作。
如果您需要真正安全的东西来验证请求是否来自您的 SugarCRM 服务器,您需要使用类似 token based authentication.
的东西
许多基于 Rails 的 API 使用特殊的控制器和路由来执行可由 API 客户端执行的操作。在您的情况下,它看起来像这样:
POST /api/v1/contacts
# routes.rb
namespace :api do
namespace :v1 do
resources :contacts
end
end
# controllers/api/v1/api_controller
class ApiController < ActionController::Base
skip_before_filter, only: [:create]
def authenticate
# @todo implement token based auth
end
end
# controllers/api/v1/contacts_controller
class Api::V1::ContactsController
before_action :authenticate
def create
@contact = Contact.new(contact_params)
# ...
end
# ...
end
我是 sugarCRM 实例的管理员,我在 heroku 上有一个 rails 应用程序。如果在 sugarCRM 中添加联系人,我希望能够自动将联系人添加到 rails 应用程序。我在我的 sugarCRM 中写了一个 before_save logic_hook:
function pushConts($bean, $event, $arguments)
{
$r = new HttpRequest('http://localhost:3000/contacts/', HttpRequest::METH_POST);
$r->addPostFields(array('first_name' => $bean->first_name, 'last_name' => $bean->last_name, 'phone' => $bean->phone_mobile,'email' => $bean->email1, ));
//$r->addHeaders(array('X-CSRF-Token'=> 'testing-csrf-token');
try
{
echo $r->send()->getBody();
} catch(HttpException $ex){
SugarApplication::appendErrorMessage("<span style='color: red; font-size: 1.8em;'>Could Not Save Contact: Rails app is down.</span>");
$queryParams = array('module' => 'Contacts', 'action' => 'ListView');
SugarApplication::redirect('index.php?' . http_build_query($queryParams));
}
当我尝试按原样发送时,rails 应用程序的控制台输出是:
Started POST "/contacts/" for 127.0.0.1 at 2015-06-18 15:30:14 -0500
Processing by ContactsController#create as */*
Parameters: {"first_name"=>"contact", "last_name"=>"one", "phone"=>"(555) 555-5555", "email"=>"phone.support@example.us"}
Can't verify CSRF token authenticity
Completed 422 Unprocessable Entity in 1ms
ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
actionpack (4.2.0) lib/action_controller/metal/request_forgery_protection.rb:181:in `handle_unverified_request'
actionpack (4.2.0) lib/action_controller/metal/request_forgery_protection.rb:209:in `handle_unverified_request'
devise (3.4.1) lib/devise/controllers/helpers.rb:251:in `handle_unverified_request'
<stack trace continues>
我知道逻辑挂钩本身有效,因为我尝试将 skip_before_filter :verify_authenticity_token
添加到我的联系人控制器,然后它按预期工作,但出于安全原因,这不是一个可行的解决方案。
如您所见,注释掉了,我尝试用 headers 发送 X-CSRF-Token
,但这也没有用。
我可以向这个逻辑挂钩或我的 rails 应用程序本身(或两者)添加什么,以便我可以将 Http 请求从我的 sugarCRM 发送到我的 rails 应用程序而不会妥协(也多)安全?
Rails CSRF 系统并非真正旨在跨域或跨服务器工作。 It leverages synchronizer tokens (cryptographically random tokens) which are bound to the user's session.
由于 Rails 和 SugarCRM 不共享用户会话,因此 Rails 无法验证来自 SugarCRM 的 CSRF 令牌。
你最好的选择是关闭它以进行 skip_before_filter, only: [:create]
的操作。
如果您需要真正安全的东西来验证请求是否来自您的 SugarCRM 服务器,您需要使用类似 token based authentication.
的东西许多基于 Rails 的 API 使用特殊的控制器和路由来执行可由 API 客户端执行的操作。在您的情况下,它看起来像这样:
POST /api/v1/contacts
# routes.rb
namespace :api do
namespace :v1 do
resources :contacts
end
end
# controllers/api/v1/api_controller
class ApiController < ActionController::Base
skip_before_filter, only: [:create]
def authenticate
# @todo implement token based auth
end
end
# controllers/api/v1/contacts_controller
class Api::V1::ContactsController
before_action :authenticate
def create
@contact = Contact.new(contact_params)
# ...
end
# ...
end