我正在尝试为我的应用创建CRUD api,它有两个模型:用户和组,通过以下方式进行多对多关联:成员资格表。
对于身份验证,我使用Devise(启用:token_authenticatable选项)
我想使用curl测试API。
注册完美无缺
curl -v -H 'Content-Type: application/json' -H 'application/vnd.greenapp.v1' -X POST http://localhost:3000/api/registrations -d "{\"user\":{\"email\":\"user1@example.com\",\"name\":\"username\",\"password\":\"secret\",\"password_confirmation\":\"secret\"}}"
带回复
{"success":true,"info":"Welcome! You have signed up successfully.","data":{"user":{"created_at":"2013-08-04T11:14:35Z","email":"user@example.com","id":2,"name":"username","updated_at":"2013-08-04T11:14:35Z"},"auth_token":"Eqp8jYsr5ExeNWbzrqef"}}* Closing connection #0
但我很难找到通过API创建群组的解决方案。我试过了
curl -v -H 'Content-Type: application/json' -H 'application/vnd.greenapp.v1' -X POST http://localhost:3000/api/groups -d "{\"group\":{\"name\":\"groupname\",\"desc\":\"group description\"}}"
返回(在服务器日志中)
RuntimeError (Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id): app/controllers/api/v1/groups_controller.rb:49:in `create'
所以这是我的小组控制器:
class Api::V1::GroupsController < ApplicationController
skip_before_filter :verify_authenticity_token,
:if => Proc.new { |c| c.request.format == 'application/json' }
respond_to :json
def new
@group = Group.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: @group }
end
end
def create
@group = Group.new(params[:group])
@group.memberships.build(user_id: current_user.id)
respond_to do |format|
if @group.save
format.html { redirect_to @group, notice: 'Group was successfully created.' }
format.json { render json: @group, status: :created, location: @group }
else
format.html { render action: "new" }
format.json { render json: @group.errors, status: :unprocessable_entity }
end
end
end
end
有什么想法吗?
更新
SessionsCotroller
class Api::V1::SessionsController < Devise::SessionsController
skip_before_filter :verify_authenticity_token,
:if => Proc.new { |c| c.request.format == 'application/json' }
respond_to :json
def create
warden.authenticate!(:scope => resource_name, :store => false, :recall => "# {controller_path}#failure")
render :status => 200,
:json => { :success => true,
:info => t("devise.sessions.signed_in"),
:data => { :auth_token => current_user.authentication_token } }
end
def destroy
warden.authenticate!(:scope => resource_name, :store => false, :recall => "#{controller_path}#failure")
current_user.reset_authentication_token!
render :status => 200,
:json => { :success => true,
:info => t("devise.sessions.signed_out"),
:data => {} }
end
def failure
render :status => 401,
:json => { :success => false,
:info => "Login Failed",
:data => {} }
end
end
答案 0 :(得分:2)
您的current_user实例为零。 作为curl命令的一部分,您需要提供登录凭据并确保您的代码使用这些凭据作为before_filter的一部分登录。
我很惊讶您没有收到身份验证例外。但也许你还没有正确实现你的身份验证系统。
要使用api登录,您确实需要使用带有用户名和密码的HTTP BASIC身份验证,或者使用某种形式的身份验证令牌。
由于您未提供有关身份验证功能的任何信息,因此无法进一步提供建议。
P.S。你真的应该为此写一个测试。
对评论的回应更新
从您的组控制器中删除skip_before_filter:verify_authenticity_token,并提供有效的身份验证令牌以及您的curl命令。我从未使用过设计或监护人,所以我不确定你是否会面临重定向问题。
我通常发现滚动我自己的身份验证要简单得多,它会集中精力确保ssl强制执行正确的控制器操作并让我考虑Web服务器的SSL证书以及所有其他小安全事项当你依赖宝石时,往往会被遗忘。