我收到了这个错误,但我不知道为什么。我特意排除了CSRF检查。 #webhook
方法即使在生产中也可以使用。其他类似的问题是关于Devise,但我没有在这个控制器中使用Devise。
stripes_controller.rb
class StripesController < ApplicationController
Stripe.api_key = ENV['STRIPE_PRIVATE']
protect_from_forgery :except => [:webhook, :create]
def show
end
def create
# Amount in cents
@amount = params[:amount]
customer = Stripe::Customer.create(
:email => params[:stripeEmail],
:source => params[:stripeToken]
)
charge = Stripe::Charge.create(
:customer => customer.id,
:amount => @amount,
:description => 'Membership Fee',
:currency => 'usd'
)
render :show
rescue Stripe::CardError => e
flash[:error] = e.message
redirect_to stripe_path
end
routes.rb
resource :stripe do
Log
Started POST "/stripe/" for 127.0.0.1 at 2018-01-03 11:58:17 -0500
Processing by StripesController#create as HTML
Parameters: {"amount"=>"100", "stripeToken"=>"tok_1BgFZ2IYOmXNPhc121HxNtw0", "stripeEmail"=>"test@example.com"}
Rendering stripes/show.haml within layouts/application
Rendered stripes/show.haml within layouts/application (2.0ms)
User Load (3.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
(2.0ms) BEGIN
(1.0ms) COMMIT
Completed 401 Unauthorized in 3533ms (ActiveRecord: 6.0ms)
Started GET "/" for 127.0.0.1 at 2018-01-03 11:58:21 -0500
默认情况下,Rails位于:debug
日志级别。 http://guides.rubyonrails.org/v5.0/debugging_rails_applications.html#log-levels
我能够通过设置
来重现它devise.rb
config.timeout_in = 1.minute # 8.hours
如果我已登录并处于活动状态,它可以正常工作,但如果会话超时,则会导致此401问题。
这是来自浏览器的请求/响应。它显示成功和302响应,而不是401.它在服务器控制台日志中显示401。
POST /stripe/ HTTP/1.1
Host: localhost:3000
Connection: keep-alive
Content-Length: 82
Cache-Control: max-age=0
Origin: http://localhost:3000
Content-Type: application/x-www-form-urlencoded
...
HTTP/1.1 302 Found
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Location: http://localhost:3000/
Content-Type: text/html; charset=utf-8
浏览器网络日志中没有一个401响应,甚至按状态排序,即使使用Preserver Log也是如此。
Rails 5.0.2
答案 0 :(得分:2)
我按照Marek的建议将问题追踪到user_signed_in?
。该功能将 HALT 执行并发出302重定向,同时在服务器日志中打印401!
devise.rb
config.timeout_in = 1.minute # 8.hours
stripes_controller.rb
class StripesController < ApplicationController
layout false
show.haml
%h2 Thank you!
%p
Your payment of
%strong= number_to_currency(@amount.to_i * 0.01)
has been received.
- if user_signed_in?
Signed in
- else
Signed out
如果用户已登录,则页面将正常加载。如果用户的会话过期,则设计将重定向并设置Flash消息!
log
Started GET "/stripe" for 127.0.0.1 at 2018-01-03 14:39:08 -0500
Processing by StripesController#show as HTML
Rendering stripes/show.haml
User Load (22.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
(1.0ms) BEGIN
(2.0ms) COMMIT
Rendered stripes/show.haml (179.2ms)
Completed 401 Unauthorized in 399ms (ActiveRecord: 52.0ms)
Started GET "/stripe" for 127.0.0.1 at 2018-01-03 14:39:09 -0500
Processing by StripesController#show as HTML
Rendering stripes/show.haml
Rendered stripes/show.haml (2.0ms)
Completed 200 OK in 219ms (Views: 99.8ms | ActiveRecord: 0.0ms)
我无法找到一种方法来检查用户是否在没有重定向的情况下登录。
https://duckduckgo.com/?q=rails+devise+%22user_signed_in%22+stop+redirecting&ia=qa
在搜索方法时, user_signed_in?
即使在Devise API文档中也是如此!我希望有一个可选的论点。
http://www.rubydoc.info/github/plataformatec/devise/Devise
所以我设置了layout false
,因此它停止使用包含application.haml
的{{1}}。我希望有更好的方法。
答案 1 :(得分:0)
HTTP代码401 Unauthorized用于身份验证(https://httpstatuses.com/401)。它与CSRF无关。在这种情况下,它会引发ActionController :: InvalidAuthenticityToken。
我非常确定您的ApplicationController中有一个需要用户身份验证的before_action(或者在routes.rb中,或者在nginx / Apache的配置中)。