Ruby版本:2.2.4 Rails版本:5.0.0.1 系统:Windows 7 大家好,
我是RoR的新手,我遵循基于令牌的认证与Ruby on Rails 5 API教程(http://tutorials.pluralsight.com/ruby-ruby-on-rails/token-based-authentication-with-ruby-on-rails-5-api) 但是,当我使用curl命令时出现错误。
我在启动rails服务器(可行)时插入命令行:
curl -H "Content-Type: application/json" -X POST -d '{"email":"example@mail.com","password":"123123123"}' http://localhost:3000/authenticate
然后发生这种情况:
{"status":400,"error":"Bad Request","exception":"#\u003cActionDispatch::ParamsParser::ParseError: 814: unexpected token at ''{email:example@mail.com,password:123123123}''\u003e","
traces":{"Application Trace":[],"Framework Trace":[{"id":0,"trace":"actionpack (5.0.0.1) lib/action_dispatch/http/parameters.rb:71:in `rescue in parse_formatted_parameters'"},{"id
":1,"trace":"actionpack (5.0.0.1) lib/action_dispatch/http/parameters.rb:65:in `parse_formatted_parameters'"},{"id":2,"trace":"actionpack (5.0.0.1) lib/action_dispatch/http/reques
t.rb:366:in `block in POST'"},{"id":3,"trace":"rack (2.0.1) lib/rack/request.rb:57:in `fetch'"},{"id":4,"trace":"rack (2.0.1) lib/rack/request.rb:57:in `fetch_header'"},{"id":5,"t
race":"actionpack (5.0.0.1) lib/action_dispatch/http/request.rb:365:in `POST'"},{"id":6,"trace":"actionpack (5.0.0.1) lib/action_controller/metal/params_wrapper.rb:282:in `_wrappe
r_enabled?'"},{"id":7,"trace":"actionpack (5.0.0.1) lib/action_controller/metal/params_wrapper.rb:231:in `process_action'"},{"id":8,"trace":"activerecord (5.0.0.1) lib/active_reco
rd/railties/controller_runtime.rb:18:in `process_action'"},{"id":9,"trace":"actionpack (5.0.0.1) lib/abstract_controller/base.rb:126:in `process'"},{"id":10,"trace":"actionpack (5
.0.0.1) lib/action_controller/metal.rb:190:in `dispatch'"},{"id":11,"trace":"actionpack (5.0.0.1) lib/action_controller/metal.rb:262:in `dispatch'"},{"id":12,"trace":"actionpack (
5.0.0.1) lib/action_dispatch/routing/route_set.rb:50:in `dispatch'"},{"id":13,"trace":"actionpack (5.0.0.1) lib/action_dispatch/routing/route_set.rb:32:in `serve'"},{"id":14,"trac
e":"actionpack (5.0.0.1) lib/action_dispatch/journey/router.rb:39:in `block in serve'"},{"id":15,"trace":"actionpack (5.0.0.1) lib/action_dispatch/journey/router.rb:26:in `each'"}
,{"id":16,"trace":"actionpack (5.0.0.1) lib/action_dispatch/journey/router.rb:26:in `serve'"},{"id":17,"trace":"actionpack (5.0.0.1) lib/action_dispatch/routing/route_set.rb:725:i
n `call'"},{"id":18,"trace":"rack (2.0.1) lib/rack/etag.rb:25:in `call'"},{"id":19,"trace":"rack (2.0.1) lib/rack/conditional_get.rb:38:in `call'"},{"id":20,"trace":"rack (2.0.1)
lib/rack/head.rb:12:in `call'"},{"id":21,"trace":"activerecord (5.0.0.1) lib/active_record/migration.rb:552:in `call'"},{"id":22,"trace":"actionpack (5.0.0.1) lib/action_dispatch/
middleware/callbacks.rb:38:in `block in call'"},{"id":23,"trace":"activesupport (5.0.0.1) lib/active_support/callbacks.rb:97:in `__run_callbacks__'"},{"id":24,"trace":"activesuppo
rt (5.0.0.1) lib/active_support/callbacks.rb:750:in `_run_call_callbacks'"},{"id":25,"trace":"activesupport (5.0.0.1) lib/active_support/callbacks.rb:90:in `run_callbacks'"},{"id"
:26,"trace":"actionpack (5.0.0.1) lib/action_dispatch/middleware/callbacks.rb:36:in `call'"},{"id":27,"trace":"actionpack (5.0.0.1) lib/action_dispatch/middleware/executor.rb:12:i
n `call'"},{"id":28,"trace":"actionpack (5.0.0.1) lib/action_dispatch/middleware/remote_ip.rb:79:in `call'"},{"id":29,"trace":"actionpack (5.0.0.1) lib/action_dispatch/middleware/
debug_exceptions.rb:49:in `call'"},{"id":30,"trace":"actionpack (5.0.0.1) lib/action_dispatch/middleware/show_exceptions.rb:31:in `call'"},{"id":31,"trace":"railties (5.0.0.1) lib
/rails/rack/logger.rb:36:in `call_app'"},{"id":32,"trace":"railties (5.0.0.1) lib/rails/rack/logger.rb:24:in `block in call'"},{"id":33,"trace":"activesupport (5.0.0.1) lib/active
_support/tagged_logging.rb:70:in `block in tagged'"},{"id":34,"trace":"activesupport (5.0.0.1) lib/active_support/tagged_logging.rb:26:in `tagged'"},{"id":35,"trace":"activesuppor
t (5.0.0.1) lib/active_support/tagged_logging.rb:70:in `tagged'"},{"id":36,"trace":"railties (5.0.0.1) lib/rails/rack/logger.rb:24:in `call'"},{"id":37,"trace":"actionpack (5.0.0.
1) lib/action_dispatch/middleware/request_id.rb:24:in `call'"},{"id":38,"trace":"rack (2.0.1) lib/rack/runtime.rb:22:in `call'"},{"id":39,"trace":"activesupport (5.0.0.1) lib/acti
ve_support/cache/strategy/local_cache_middleware.rb:28:in `call'"},{"id":40,"trace":"actionpack (5.0.0.1) lib/action_dispatch/middleware/executor.rb:12:in `call'"},{"id":41,"trace
":"actionpack (5.0.0.1) lib/action_dispatch/middleware/static.rb:136:in `call'"},{"id":42,"trace":"rack (2.0.1) lib/rack/sendfile.rb:111:in `call'"},{"id":43,"trace":"railties (5.
0.0.1) lib/rails/engine.rb:522:in `call'"},{"id":44,"trace":"puma (3.6.0) lib/puma/configuration.rb:225:in `call'"},{"id":45,"trace":"puma (3.6.0) lib/puma/server.rb:578:in `handl
e_request'"},{"id":46,"trace":"puma (3.6.0) lib/puma/server.rb:415:in `process_client'"},{"id":47,"trace":"puma (3.6.0) lib/puma/server.rb:275:in `block in run'"},{"id":48,"trace"
:"puma (3.6.0) lib/puma/thread_pool.rb:116:in `call'"},{"id":49,"trace":"puma (3.6.0) lib/puma/thread_pool.rb:116:in `block in spawn_thread'"}],"Full Trace":[{"id":0,"trace":"acti
onpack (5.0.0.1) lib/action_dispatch/http/parameters.rb:71:in `rescue in parse_formatted_parameters'"},{"id":1,"trace":"actionpack (5.0.0.1) lib/action_dispatch/http/parameters.rb
:65:in `parse_formatted_parameters'"},{"id":2,"trace":"actionpack (5.0.0.1) lib/action_dispatch/http/request.rb:366:in `block in POST'"},{"id":3,"trace":"rack (2.0.1) lib/rack/req
uest.rb:57:in `fetch'"},{"id":4,"trace":"rack (2.0.1) lib/rack/request.rb:57:in `fetch_header'"},{"id":5,"trace":"actionpack (5.0.0.1) lib/action_dispatch/http/request.rb:365:in `
POST'"},{"id":6,"trace":"actionpack (5.0.0.1) lib/action_controller/metal/params_wrapper.rb:282:in `_wrapper_enabled?'"},{"id":7,"trace":"actionpack (5.0.0.1) lib/action_controlle
r/metal/params_wrapper.rb:231:in `process_action'"},{"id":8,"trace":"activerecord (5.0.0.1) lib/active_record/railties/controller_runtime.rb:18:in `process_action'"},{"id":9,"trac
e":"actionpack (5.0.0.1) lib/abstract_controller/base.rb:126:in `process'"},{"id":10,"trace":"actionpack (5.0.0.1) lib/action_controller/metal.rb:190:in `dispatch'"},{"id":11,"tra
ce":"actionpack (5.0.0.1) lib/action_controller/metal.rb:262:in `dispatch'"},{"id":12,"trace":"actionpack (5.0.0.1) lib/action_dispatch/routing/route_set.rb:50:in `dispatch'"},{"i
d":13,"trace":"actionpack (5.0.0.1) lib/action_dispatch/routing/route_set.rb:32:in `serve'"},{"id":14,"trace":"actionpack (5.0.0.1) lib/action_dispatch/journey/router.rb:39:in `bl
ock in serve'"},{"id":15,"trace":"actionpack (5.0.0.1) lib/action_dispatch/journey/router.rb:26:in `each'"},{"id":16,"trace":"actionpack (5.0.0.1) lib/action_dispatch/journey/rout
er.rb:26:in `serve'"},{"id":17,"trace":"actionpack (5.0.0.1) lib/action_dispatch/routing/route_set.rb:725:in `call'"},{"id":18,"trace":"rack (2.0.1) lib/rack/etag.rb:25:in `call'"
},{"id":19,"trace":"rack (2.0.1) lib/rack/conditional_get.rb:38:in `call'"},{"id":20,"trace":"rack (2.0.1) lib/rack/head.rb:12:in `call'"},{"id":21,"trace":"activerecord (5.0.0.1)
lib/active_record/migration.rb:552:in `call'"},{"id":22,"trace":"actionpack (5.0.0.1) lib/action_dispatch/middleware/callbacks.rb:38:in `block in call'"},{"id":23,"trace":"active
support (5.0.0.1) lib/active_support/callbacks.rb:97:in `__run_callbacks__'"},{"id":24,"trace":"activesupport (5.0.0.1) lib/active_support/callbacks.rb:750:in `_run_call_callbacks
'"},{"id":25,"trace":"activesupport (5.0.0.1) lib/active_support/callbacks.rb:90:in `run_callbacks'"},{"id":26,"trace":"actionpack (5.0.0.1) lib/action_dispatch/middleware/callbac
ks.rb:36:in `call'"},{"id":27,"trace":"actionpack (5.0.0.1) lib/action_dispatch/middleware/executor.rb:12:in `call'"},{"id":28,"trace":"actionpack (5.0.0.1) lib/action_dispatch/mi
ddleware/remote_ip.rb:79:in `call'"},{"id":29,"trace":"actionpack (5.0.0.1) lib/action_dispatch/middleware/debug_exceptions.rb:49:in `call'"},{"id":30,"trace":"actionpack (5.0.0.1
) lib/action_dispatch/middleware/show_exceptions.rb:31:in `call'"},{"id":31,"trace":"railties (5.0.0.1) lib/rails/rack/logger.rb:36:in `call_app'"},{"id":32,"trace":"railties (5.0
.0.1) lib/rails/rack/logger.rb:24:in `block in call'"},{"id":33,"trace":"activesupport (5.0.0.1) lib/active_support/tagged_logging.rb:70:in `block in tagged'"},{"id":34,"trace":"a
ctivesupport (5.0.0.1) lib/active_support/tagged_logging.rb:26:in `tagged'"},{"id":35,"trace":"activesupport (5.0.0.1) lib/active_support/tagged_logging.rb:70:in `tagged'"},{"id":
36,"trace":"railties (5.0.0.1) lib/rails/rack/logger.rb:24:in `call'"},{"id":37,"trace":"actionpack (5.0.0.1) lib/action_dispatch/middleware/request_id.rb:24:in `call'"},{"id":38,
"trace":"rack (2.0.1) lib/rack/runtime.rb:22:in `call'"},{"id":39,"trace":"activesupport (5.0.0.1) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'"},{"id"
:40,"trace":"actionpack (5.0.0.1) lib/action_dispatch/middleware/executor.rb:12:in `call'"},{"id":41,"trace":"actionpack (5.0.0.1) lib/action_dispatch/middleware/static.rb:136:in
`call'"},{"id":42,"trace":"rack (2.0.1) lib/rack/sendfile.rb:111:in `call'"},{"id":43,"trace":"railties (5.0.0.1) lib/rails/engine.rb:522:in `call'"},{"id":44,"trace":"puma (3.6.0
) lib/puma/configuration.rb:225:in `call'"},{"id":45,"trace":"puma (3.6.0) lib/puma/server.rb:578:in `handle_request'"},{"id":46,"trace":"puma (3.6.0) lib/puma/server.rb:415:in `p
rocess_client'"},{"id":47,"trace":"puma (3.6.0) lib/puma/server.rb:275:in `block in run'"},{"id":48,"trace":"puma (3.6.0) lib/puma/thread_pool.rb:116:in `call'"},{"id":49,"trace":
"puma (3.6.0) lib/puma/thread_pool.rb:116:in `block in spawn_thread'"}]}}
更新:如果我使用此curl命令,我可以连接:
curl -v -H 'Content-Type: application/json' -H 'Accept: application/json' -X POST http://localhost:3000/authenticate -d "{\"email\":\"example@mail.com\",\"password\":\"123123123\"}"
但后来我收到了这个错误:
Note: Unnecessary use of -X or --request, POST is already inferred.
* Could not resolve host: application
* Closing connection 0
curl: (6) Could not resolve host: application
Note: Unnecessary use of -X or --request, POST is already inferred.
* Could not resolve host: application
* Closing connection 1
curl: (6) Could not resolve host: application
Note: Unnecessary use of -X or --request, POST is already inferred.
* Trying ::1...
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3000 (#2)
> POST /authenticate HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.50.1
> Accept: */*
> Content-Length: 51
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 51 out of 51 bytes
< HTTP/1.1 401 Unauthorized
< X-Frame-Options: SAMEORIGIN
< X-XSS-Protection: 1; mode=block
< X-Content-Type-Options: nosniff
< Content-Type: application/json; charset=utf-8
< Cache-Control: no-cache
< X-Request-Id: 0c6cd1b4-0482-4536-9395-106f5dd2bf5f
< X-Runtime: 0.017592
< Transfer-Encoding: chunked
<
{"error":{"user_authentication":["invalid credentials"]}}* Connection #2 to host localhost left intact
有人知道我做错了吗?
这是我的代码:
class AuthenticateUser
prepend SimpleCommand
def initialize(email, password)
@email = email
@password = password
end
def call
JsonWebToken.encode(user_id: user.id) if user
end
private
attr_accessor :email, :password
def user
user = User.find_by_email(email)
return user if user && user.authenticate(password)
errors.add :user_authentication, 'invalid credentials'
nil
end
end
class AuthorizeApiRequest
prepend SimpleCommand
def initialize(headers = {})
@headers = headers
end
def call
user
end
private
attr_reader :headers
def user
@user ||= User.find(decoded_auth_token[:user_id]) if decoded_auth_token
@user || errors.add(:token, 'Invalid token') && nil
end
def decoded_auth_token
@decoded_auth_token ||= JsonWebToken.decode(http_auth_header)
end
def http_auth_header
if headers['Authorization'].present?
return headers['Authorization'].split(' ').last
else
errors.add(:token, 'Missing token')
end
nil
end
end
在控制器中,我有以下3个控制器:1。application_controller.rb
class ApplicationController < ActionController::API
before_action :authenticate_request
attr_reader :current_user
private
def authenticate_request
@current_user = AuthorizeApiRequest.call(request.headers).result
render json: { error: 'Not Authorized' }, status: 401 unless @current_user
end
end
认证controller.rb
class AuthenticationController < ApplicationController
skip_before_action :authenticate_request
def authenticate
command = AuthenticateUser.call(params[:email], params[:password])
if command.success?
render json: { auth_token: command.result }
else
render json: { error: command.errors }, status: :unauthorized
end
end
end
items_controller.rb
class ItemsController < ApplicationController
before_action :set_item, only: [:show, :update, :destroy]
# GET /items
def index
@items = Item.all
render json: @items
end
# GET /items/1
def show
render json: @item
end
# POST /items
def create
@item = Item.new(item_params)
if @item.save
render json: @item, status: :created, location: @item
else
render json: @item.errors, status: :unprocessable_entity
end
end
# PATCH/PUT /items/1
def update
if @item.update(item_params)
render json: @item
else
render json: @item.errors, status: :unprocessable_entity
end
end
# DELETE /items/1
def destroy
@item.destroy
end
private
# Use callbacks to share common setup or constraints between actions.
def set_item
@item = Item.find(params[:id])
end
# Only allow a trusted parameter "white list" through.
def item_params
params.require(:item).permit(:name, :description)
end
end
然后我有routes.rb
Rails.application.routes.draw do
resources :items
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
post 'authenticate', to: 'authentication#authenticate'
end