【问题标题】:How do I generate a CSRF token from the Rails console?如何从 Rails 控制台生成 CSRF 令牌?
【发布时间】:2014-07-18 07:01:49
【问题描述】:

我正在尝试发出经过身份验证的发布请求,并且我需要 CSRF。当我登录时,由于某种原因它没有生成_csrf_token

2.0.0p247 :126 >   app.post '/community_members/login', {"refinery_user[login]"=>'chloe', 'refinery_user[password]'=>'test'}
 => 302
2.0.0p247 :127 > app.session
 => {"warden.user.refinery_user.key"=>[[56], "$2a$10$gr/rTcQfuXnes1Zml3qOPu"], "session_id"=>"f77d89cef9ff1710890f575b479bb690"}

我在登录前尝试了app.session[:_csrf_token] ||= SecureRandom.base64(32),但它总是被删除。我也尝试过先获取登录表单,但_csrf_token仍然没有设置。

2.0.0p247 :133 >   app.get '/community_members/sign_in'
2.0.0p247 :134 > app.response # authenticity_token is burried in the raw HTML
2.0.0p247 :136 >   app.post '/community_members/login', {"refinery_user[login]"=>'chloe', 'refinery_user[password]'=>'test'}
2.0.0p247 :137 > app.session
 => {"warden.user.refinery_user.key"=>[[56], "$2a$10$gr/rTcQfuXnes1Zml3qOPu"], "session_id"=>"c2c564229e55b81ca788788558d7d11a"}

如何手动生成令牌以传递给发布请求?


哦,好的,我想我需要将authentity_token(在获取登录表单后在会话中设置)提交到登录表单,然后将其永久放入会话中!这有效:

app.post '/community_members/login', {'authenticity_token'=>'GfT5GtcUmYQ927oNQmh2MR0NKQucGSx8mtMg3Ph9kXw=', "refinery_user[login]"=>'chloe', 'refinery_user[password]'=>'test'}

这是一个完整的例子:https://stackoverflow.com/a/23899701/148844

【问题讨论】:

    标签: ruby-on-rails csrf refinerycms


    【解决方案1】:

    我觉得使用 Nokogiri 解析响应有点繁重,所以我编写了一个简单的正则表达式来从响应中提取真实性令牌。

    app.get  '/api_with_form'
    authenticity_token = app.response.body.match(/<[^<]+authenticity_token[^>]+value="([^"]+)"[^>]+>/)[1]
    

    我用这个登录

    app.get  '/users/sign_in'
    authenticity_token = app.response.body.match(/<[^<]+authenticity_token[^>]+value="([^"]+)"[^>]+>/)[1]
    app.post '/users/sign_in', 'user[email]' => 'my_username', 'user[password]' => 'my_password', authenticity_token: authenticity_token
    

    【讨论】:

    • 非常感谢!
    【解决方案2】:

    除非您在执行app.post 之前加载页面,否则一开始就不会生成 CSRF 令牌。手动生成一个新的将无济于事,因为它与服务器上存储的内容不匹配,这可能是一些 null 值。

    您需要加载页面,解析出 CSRF 令牌,然后使用该令牌。

    或者,您可以加载表单,尝试从 app.session[:_csrf_token] 中读取 CSRF 令牌并使用它。

    【讨论】:

    • 即使我先获取登录表单,然后发布,session[:_csrf_token] 也没有设置。
    • 我必须在登录时提交authentity_token!
    • @Chloe,我假设接受意味着您意识到必须先加载登录页面,然后获取令牌?
    【解决方案3】:

    我在 Rails 控制台中使用这些命令:

    app_controller = ActionController::Base::ApplicationController.new
    app_controller.request = ActionDispatch::Request.new({})
    app_controller.send(:form_authenticity_token)
    

    【讨论】:

      猜你喜欢
      • 2010-12-20
      • 2014-01-21
      • 2015-08-15
      • 2015-08-16
      • 2014-08-31
      • 2015-10-27
      • 2012-02-01
      • 2011-08-24
      • 2018-01-18
      相关资源
      最近更新 更多