Rails 7支付成功后触发ActionController::InvalidAuthenticityToken问题解决
问题原因
Rails框架默认对所有POST、PUT、DELETE请求做CSRF(跨站请求伪造)验证——简单说就是防止别人冒充用户在你网站上提交恶意请求。验证逻辑是:你的页面会生成一个唯一的CSRF Token,用户提交请求时必须带上这个Token,Rails会对比Token是否匹配。
但Easebuzz支付成功后的回调是第三方服务器(Easebuzz的服务器)直接给你的orders#successE接口发POST请求,它根本拿不到你网站给用户生成的CSRF Token,自然没法在请求里带上。所以Rails验证失败,就抛出了ActionController::InvalidAuthenticityToken错误,你猜的核心原因是对的:系统要验证Token但拿不到合法的,所以报错。
解决方法
- 临时快速解决:在你的
OrdersController里仅给successE方法跳过CSRF验证(别全局跳过,避免安全风险):
class OrdersController < ApplicationController # 只针对successE方法关闭CSRF验证 skip_before_action :verify_authenticity_token, only: [:successE] # 你的payE方法代码 def payE @payment_response = Easebuzz::Payment.initiate({ "txnid" => "#{@order.id}", "amount" => amount.to_f, "firstname" => current_user.name, "email" => current_user.email, "phone" => current_user.phone_number, "surl" => "http://localhost:3000/orders/#{@order.id}/successE", "furl" => "http://localhost:3000/response.php", "address1" => address, "country" => "India", #"zipcode" => "123123" }) if @payment_response['status'] == 1 data = @payment_response['data'] redirect_to("https://testpay.easebuzz.in/pay/#{data}", allow_other_host: true, status: 303) end end # 你的回调处理方法 def successE # 这里写支付成功后的订单状态更新等逻辑 end end
- 更安全的必做步骤:跳过CSRF后,一定要验证回调的合法性,确保是Easebuzz官方发的请求。根据Easebuzz的文档,他们会在回调参数里附带签名字段,你可以用自己的商户密钥,按照官方给出的签名算法重新计算签名,和回调里的签名对比——只有签名一致时才处理订单状态,不一致直接拒绝请求。
内容的提问来源于stack exchange,提问作者uma
相关产品推荐
相关产品推荐

