我们正在创建一个Java客户端,以便与Ruby on Rails服务器连接,用于库存系统项目(适用于学校)。
我们正在使用的客户端应该执行HTTP GET来请求信息和HTTP POST来更新或创建新信息(是的,我们知道HTTP PUT ......)。
不幸的是,当我们尝试执行HTTP帖子时,我们遇到了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动作完美无缺,并且使用有效的用户名和密码触发身份验证操作(例如,工作正常......)。当我们尝试将更新POST到更新操作时,会发生我们的问题。当我们尝试它时,我们得到一个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客户端?非常感谢任何帮助。
答案 0 :(得分:3)
您是否在POST数据中包含CSRF令牌?
请参阅此链接:http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection/ClassMethods.html
默认情况下启用protect_from_forgery
,这使得Rails需要任何非GET请求的真实性令牌。 Rails会自动在使用表单助手创建的表单中包含真实性令牌,但我猜是因为你要构建自己的表单来发布,所以你不包括令牌。