Ruby on rails 使用curl连接到轨道会产生错误的响应

Ruby on rails 使用curl连接到轨道会产生错误的响应,ruby-on-rails,api,curl,devise,ruby-on-rails-4,Ruby On Rails,Api,Curl,Devise,Ruby On Rails 4,我已经实现了Matteo Melanis伟大的博客文章。它与Chrome扩展完美配合。然而,当我尝试使用cUrl获取用户身份验证令牌时,我遇到了一个奇怪的问题 首先,使用Postman获取(成功)身份验证的development.log条目: Started POST "/api/v1/tokens.json?email=my@mail.com&password=[FILTERED]" for 127.0.0.1 at 2013-11-25 11:28:21 +0100 Processi

我已经实现了Matteo Melanis伟大的博客文章。它与Chrome扩展完美配合。然而,当我尝试使用cUrl获取用户身份验证令牌时,我遇到了一个奇怪的问题

首先,使用Postman获取(成功)身份验证的development.log条目:

Started POST "/api/v1/tokens.json?email=my@mail.com&password=[FILTERED]" for 127.0.0.1 at 2013-11-25 11:28:21 +0100
Processing by Api::V1::TokensController#create as JSON
  Parameters: {"email"=>"my@mail.com", "password"=>"[FILTERED]"}
  [1m[36mUser Load (1.4ms)[0m  [1mSELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY "users"."id" ASC LIMIT 1[0m
Entered create method
  [1m[35mUser Load (3.9ms)[0m  SELECT "users".* FROM "users" WHERE "users"."email" = 'my@mail.com' LIMIT 1
Completed 200 OK in 99ms (Views: 0.3ms | ActiveRecord: 5.3ms)
然后,当我运行
$curl-xpost”https://localhost:3000/api/v1/tokens.json?email=my@mail.com&password=somepassword“-d”电子邮件=my@mail.com&password=somepassword“-v-k-i
,我得到

Started POST "/api/v1/tokens.json?email=my@mail.com&password=[FILTERED]" for 127.0.0.1 at 2013-11-25 11:29:01 +0100
Processing by Api::V1::TokensController#create as JSON
  Parameters: {"email"=>"my@mail.com", "password"=>"[FILTERED]"}
Completed 401 Unauthorized in 12ms
您可能会问,为什么我将参数同时作为HTTP Post数据和查询字符串提供。嗯,我对curl-lib样本的初步研究表明了前者,而邮递员的成功查询表明了后者。我试过所有这些组合,但都不起作用,所以我很迷茫

Api::V1::tokenscoontroller
中,我在调用create方法时添加了日志记录,即

class Api::V1::TokensController  < ApplicationController
  skip_before_filter :verify_authenticity_token
  respond_to :json

  def create

    Rails.logger.debug("Entered create method")

    email = params[:email]
    password = params[:password]
    if request.format != :json
      render :status=>406, :json=>{:message=>"The request must be json"}
      return
    end

    if email.nil? or password.nil?
       render :status=>400,
              :json=>{:message=>"The request must contain the user email and password."}
       return
    end

    @user=User.find_by_email(email.downcase)

    if @user.nil?
      logger.info("User #{email} failed signin, user cannot be found.")
      render :status=>401, :json=>{:message=>"Invalid email or password."}
      return
    end

    # http://rdoc.info/github/plataformatec/devise/master/Devise/Models/TokenAuthenticatable
    @user.ensure_authentication_token!

    if not @user.valid_password?(password)
      logger.info("User #{email} failed signin, password \"#{password}\" is invalid")
      render :status=>401, :json=>{:message=>"Invalid email or password."}
    else
      render :status=>200, :json=>{:token=>@user.authentication_token}
    end
  end

  def destroy
    @user=User.find_by_authentication_token(params[:id])
    if @user.nil?
      logger.info("Token not found.")
      render :status=>404, :json=>{:message=>"Invalid token."}
    else
      @user.reset_authentication_token!
      render :status=>200, :json=>{:token=>params[:id]}
    end
  end

end
class Api::V1::TokensController406,:json=>{:message=>“请求必须是json”}
返回
结束
如果email.nil?还是密码。零?
渲染:状态=>400,
:json=>{:message=>“请求必须包含用户电子邮件和密码。”}
返回
结束
@用户=用户。通过电子邮件查找(email.downcase)
如果@user.nil?
info(“用户#{email}登录失败,找不到用户。”)
render:status=>401,:json=>{:message=>“无效的电子邮件或密码。”}
返回
结束
# http://rdoc.info/github/plataformatec/devise/master/Devise/Models/TokenAuthenticatable
@user.sure\u身份验证\u令牌!
如果不是@user.valid\u密码?(密码)
logger.info(“用户{email}登录失败,密码\”{password}\“无效”)
render:status=>401,:json=>{:message=>“无效的电子邮件或密码。”}
其他的
render:status=>200,:json=>{:token=>@user.authentication\u token}
结束
结束
def销毁
@user=user.find\u by\u authentication\u令牌(params[:id])
如果@user.nil?
logger.info(“找不到令牌”)
render:status=>404,:json=>{:message=>“无效令牌”。}
其他的
@user.reset\u身份验证\u令牌!
render:status=>200,:json=>{:token=>params[:id]}
结束
结束
结束
从日志中可以看出,create方法在第一个位置被调用,而不是在第二个位置被调用。这就好像
Api::V1::tokenscocontroller
skip_before_filter:verify_authenticity_token
被完全忽略。但这怎么可能呢


非常感谢您的任何建议

我就是这么做的。对于常规html视图,为了方便用户,我希望继续使用cookie。对于(移动)RESTAPI,我想禁用Cookie,因为整个过程都将使用
auth_token

我不是Rails/Desive的超级英雄,所以我对此有点动摇,但我认为这应该没问题。。。无论如何:在完全点击令牌控制器之前,我禁用了身份验证。为了从tokens控制器中获得合理的信息,您必须提供匹配的电子邮件/密码凭据对,因此我(目前)看不到这种方法存在任何明显的安全漏洞

因此,我的新TokensController如下所示:

class Api::V1::TokensController  < ApplicationController
  skip_before_filter :verify_authenticity_token
  skip_before_filter :authenticate_player!
  respond_to :json

  def create
    # ....
class Api::V1::TokensController
希望这能帮助其他人。如果您对可能的安全问题有任何反馈,我们将不胜感激

更新:


我忘了提到,到目前为止,整个应用程序都是通过HTTPS进行通信的。

我的直觉是,您没有为json正确发送curl。看看chrome开发工具中的网络选项卡,您可以将请求复制为cURL格式。尝试将其与您正在发送的内容进行比较,以查看缺少的内容。尝试使用类似于
curl-d''的curl的basic posthttps://localhost:3000/api/v1/tokens.json?email=my@mail.com&password=password
我也看到了您的请求,并且
https
请求localhost查看是否需要这样做如果需要,然后,也许您提供了curl证书或使用
--无检查证书
,无论哪种方式,它都会工作,因为我一直在使用它,这要感谢这三个方面的宝贵建议。最后,@Slicedpan引导我找到了解决方案——似乎在使用Postman时设置了cookie。我会在适当的时候写一个答案。:)邮递员将使用为域设置的任何现有Cookie(过去给我带来了一些麻烦!)