1

我正在尝试为我的应用程序创建 CRUD api,它有两个模型:用户和组,它们通过 :memberships 表具有多对多关联。

对于身份验证,我使用设计(启用 :token_authenticable 选项)

我想使用 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

有任何想法吗?

更新

会话控制器

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
4

1 回答 1

2

您的 current_user 实例为零。作为 curl 命令的一部分,您需要提供登录凭据并确保您的代码使用这些凭据作为 before_filter 的一部分登录。

我很惊讶您没有收到身份验证异常。但也许您没有正确实施您的身份验证系统。

要使用 api 登录,您确实需要使用带有用户名和密码的 HTTP BASIC 身份验证或使用某种形式的身份验证令牌。

由于您没有提供有关您的身份验证功能的任何信息,因此无法提供进一步的建议。

ps 你真的应该为此写一个测试。

更新回应评论

从您的组控制器中删除 skip_before_filter :verify_authenticity_token 并提供有效的身份验证令牌以及您的 curl 命令。我从未使用过设计或看守,所以我不完全确定您是否会面临重定向问题。

我通常发现推出自己的身份验证要简单得多,它专注于确保 ssl 被强制执行正确的控制器操作,并让我考虑 Web 服务器的 SSL 证书以及所有其他倾向于当您依赖宝石时会忘记。

于 2013-08-04T11:49:26.733 回答