发送 HTTP POST 时出现 InvalidAuthenticityToken 异常

发布于 2024-10-04 16:21:16 字数 3078 浏览 1 评论 0原文

我们正在为库存系统项目(针对学校)创建一个 Java 客户端来与 Ruby on Rails 服务器交互。

我们使用的客户端应该执行 HTTP GET 来请求信息,并执行 HTTP POST 来更新或创建新信息(是的,我们知道 HTTP PUT...)。

不幸的是,当我们尝试执行 HTTP post 时,遇到了 InvalidAuthenticityToken 错误。我们通过 HTTP 基本身份验证进行身份验证,我们的控制器如下所示:

class UsersController < ApplicationController

  before_filter :authenticate

  def show
    @user = User.find(params[:id])
    #@user = User.all
    render :xml => @user.to_xml
  end

  def update
    @user = User.find(params[:id])

    if @user.update_attributes(params[:user])
      render :text => 'Success!'
    else
      render :text => 'No success!'
    end
  end

private
  def authenticate
    logger.info("Entering Authen..")
    authenticate_or_request_with_http_basic do |username, password|
      logger.info("Time: #{Time.now}, username: #{username}, password: #{password}")
      User.authenticate(username, password)
    end
  end

end

show 操作完美运行,并且使用有效的用户名和密码触发身份验证操作(例如,工作正常...)。当我们尝试将更新发布到更新操作时,就会出现问题。当我们尝试它时,我们会收到 InvalidAuthenticityToken 异常。以下内容来自我们的开发日志:

#Successful GET
Processing UsersController#show (for 10.18.2.84 at 2010-11-24 19:02:42) [GET]
  Parameters: {"id"=>"2"}
Entering Authen..
Filter chain halted as [:authenticate] rendered_or_redirected.
Completed in 3ms (View: 2, DB: 0) | 401 Unauthorized [http://10.18.2.84/users/show/2]

Processing UsersController#show (for 10.18.2.84 at 2010-11-24 19:02:43) [GET]
  Parameters: {"id"=>"2"}
Entering Authen..
Time: Wed Nov 24 19:02:43 -0600 2010, username: admin, password: pass
  [4;36;1mUser Load (1.0ms)[0m   [0;1mSELECT * FROM "users" WHERE (user_name = 'admin' AND password = 'pass') LIMIT 1[0m
  [4;35;1mUser Load (0.0ms)[0m   [0mSELECT * FROM "users" WHERE ("users"."id" = 2) [0m
Completed in 18ms (View: 2, DB: 1) | 200 OK [http://10.18.2.84/users/show/2]

#Unsuccessful POST    
Processing UsersController#update (for 10.18.2.84 at 2010-11-24 19:03:06) [POST]
  Parameters: {"id"=>"2", "first-name"=>"Macky"}

ActionController::InvalidAuthenticityToken 
(ActionController::InvalidAuthenticityToken):

我们担心的是,它甚至没有尝试验证基本身份验证 - 据我们所知,它跳过了过滤器和整个控制器。我们的代码在客户端中非常普通(为了便于理解,我们对其进行了编辑):

            DefaultHttpClient httpClient = new DefaultHttpClient();
        myCredentials = new UsernamePasswordCredentials( username, password );

        //Set Provider
        provider = new BasicCredentialsProvider();
        provider.setCredentials(scope, myCredentials);

        //Set Credentials
        httpClient.setCredentialsProvider( provider );

            ArrayList<NameValuePair> formparams = new ArrayList<NameValuePair>();
            formparams.add(new BasicNameValuePair("first-name", "Macky"));

            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(formparams, "UTF-8");

            //Set the post
            post = new HttpPost( url );

            post.setEntity(formEntity);

            response = httpClient.execute( post );

那么,我们是在 Rails 中做错了什么,还是在 Java Jakarta 客户端中做错了?非常感谢任何帮助。

We're creating a Java client to interface with a Ruby on Rails server for an inventory system project (for school).

The client that we're using is supposed to do HTTP GET's to request information and HTTP POST's to update or create new information (yes, we know about HTTP PUT...).

Unfortunately, we are running into a InvalidAuthenticityToken error when we try to do a HTTP post. We authenticate through HTTP basic authentication and our controllers look like this:

class UsersController < ApplicationController

  before_filter :authenticate

  def show
    @user = User.find(params[:id])
    #@user = User.all
    render :xml => @user.to_xml
  end

  def update
    @user = User.find(params[:id])

    if @user.update_attributes(params[:user])
      render :text => 'Success!'
    else
      render :text => 'No success!'
    end
  end

private
  def authenticate
    logger.info("Entering Authen..")
    authenticate_or_request_with_http_basic do |username, password|
      logger.info("Time: #{Time.now}, username: #{username}, password: #{password}")
      User.authenticate(username, password)
    end
  end

end

The show action works perfectly and the authentication action is triggered with a valid username and password (e.g., working fine...). Our problem happens when we attempt to POST an update to the update action. When we attempt it, we get an InvalidAuthenticityToken exception. The following is from our development log:

#Successful GET
Processing UsersController#show (for 10.18.2.84 at 2010-11-24 19:02:42) [GET]
  Parameters: {"id"=>"2"}
Entering Authen..
Filter chain halted as [:authenticate] rendered_or_redirected.
Completed in 3ms (View: 2, DB: 0) | 401 Unauthorized [http://10.18.2.84/users/show/2]

Processing UsersController#show (for 10.18.2.84 at 2010-11-24 19:02:43) [GET]
  Parameters: {"id"=>"2"}
Entering Authen..
Time: Wed Nov 24 19:02:43 -0600 2010, username: admin, password: pass
  [4;36;1mUser Load (1.0ms)[0m   [0;1mSELECT * FROM "users" WHERE (user_name = 'admin' AND password = 'pass') LIMIT 1[0m
  [4;35;1mUser Load (0.0ms)[0m   [0mSELECT * FROM "users" WHERE ("users"."id" = 2) [0m
Completed in 18ms (View: 2, DB: 1) | 200 OK [http://10.18.2.84/users/show/2]

#Unsuccessful POST    
Processing UsersController#update (for 10.18.2.84 at 2010-11-24 19:03:06) [POST]
  Parameters: {"id"=>"2", "first-name"=>"Macky"}

ActionController::InvalidAuthenticityToken 
(ActionController::InvalidAuthenticityToken):

Our concern is that it isn't even attempting to authenticate the basic authentication -- it's skipping the filter and the entire controller as far as we can tell. Our code is pretty vanilla in the client (this is edited down for comprehensibility from what it actually is):

            DefaultHttpClient httpClient = new DefaultHttpClient();
        myCredentials = new UsernamePasswordCredentials( username, password );

        //Set Provider
        provider = new BasicCredentialsProvider();
        provider.setCredentials(scope, myCredentials);

        //Set Credentials
        httpClient.setCredentialsProvider( provider );

            ArrayList<NameValuePair> formparams = new ArrayList<NameValuePair>();
            formparams.add(new BasicNameValuePair("first-name", "Macky"));

            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(formparams, "UTF-8");

            //Set the post
            post = new HttpPost( url );

            post.setEntity(formEntity);

            response = httpClient.execute( post );

So, is it with Rails that we're doing something wrong or is it with the Java Jakarta client? Any help is greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

尸血腥色 2024-10-11 16:21:16

您是否在 POST 数据中包含 CSRF 令牌?

请参阅此链接: http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection /ClassMethods.html

默认情况下,protect_from_forgery 处于启用状态,这使得 Rails 需要为任何非 GET 请求提供真实性令牌。 Rails 会自动在使用表单助手创建的表单中包含真实性令牌,但我猜由于您正在构建自己的表单来发布,因此您不会包含令牌。

Are you including the CSRF token in your POST data?

See this link: http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection/ClassMethods.html

By default protect_from_forgery is enabled which makes Rails require an authenticity token for any non-GET requests. Rails will automatically include the authenticity token in forms created with the form helpers but I'm guessing since you're building your own form to post, you're not including the token.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文