Reputation: 1803
I am trying to create CRUD api for my app, which has two models: User and Group, which have many-to-many association through :memberships table.
For authentication I use Devise (with :token_authenticatable option enabled)
I want to test API using curl.
Sign Up works perfectly
curl -v -H 'Content-Type: application/json' -H 'application/vnd.greenapp.v1' -X POST http://localhost:3000/api/registrations -d "{\"user\":{\"email\":\"[email protected]\",\"name\":\"username\",\"password\":\"secret\",\"password_confirmation\":\"secret\"}}"
with response
{"success":true,"info":"Welcome! You have signed up successfully.","data":{"user":{"created_at":"2013-08-04T11:14:35Z","email":"[email protected]","id":2,"name":"username","updated_at":"2013-08-04T11:14:35Z"},"auth_token":"Eqp8jYsr5ExeNWbzrqef"}}* Closing connection #0
but I am struggling to find solution to create groups via API. I tried
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\"}}"
which returns (in server logs)
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'
So here is my groups controller:
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
Any ideas?
Update
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
Upvotes: 1
Views: 1278
Reputation: 12837
Your current_user instance is nil. As part of your curl command you will need to supply the login credentials and ensure that your code logs in using those credentials as part of your before_filter.
I'm surprised you are not getting an authentication exception. But maybe you haven't implemented your authentication system properly.
To log in with an api you really need to be using HTTP BASIC authentication with a user name and password or to use some form of auth token.
Unable to advise further as you have not supplied any information about your authentication functionality.
p.s. You really should write a test for this.
UPDATE IN RESPONSE TO COMMENTS
Remove the skip_before_filter :verify_authenticity_token from your groups controller and supply a valid auth token along with your curl command. I've never used devise or warden so I'm not entirely sure if you are going to face redirect issues.
I usually find it is far simpler to roll my own authentication and it focuses the mind on making sure that ssl is forced on the right controller actions and gets me thinking about SSL certs for the web server and all those other little security things that tend to get forgotten about when you rely on a gem.
Upvotes: 2