我想通过JSON POST在rails服务器上创建一个'image'对象。这工作得很好,但现在我添加了用户身份验证,它不再起作用了。 我使用gem'depaise'进行身份验证。 注册,登录和注销与json完美配合。
user.rb:
class User < ActiveRecord::Base
has_many :images
attr_accessible :name, :email, :password, :password_confirmation, :remember_me, :encrypted_password
has_secure_password
validates :email, format: /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i, uniqueness: true
end
images_controller:
class ImagesController < ApplicationController
before_filter :require_login #checks if user is logged in before user accesses images
respond_to :json
def index
@images = current_user.images
respond_to do |format|
format.html { }
format.json { render :json => {:success => true,
:info => "images",
:data => @images } }
end
end
def edit
@image = current_user.images.find(params[:id])
end
def new
@image = current_user.images.build
end
def create
@image = current_user.images.build(params[:image])
respond_to do |format|
if @image.save
format.html { redirect_to images_path }
format.json { render :json => @image }
else
format.html { render "new" }
format.json { render json: @image.errors, status: :unprocessable_entity }
end
end #respond_to
end
private
def require_login
unless user_signed_in? #in application_controller
redirect_to login_path,
alert: "Login first."
end
end
end
sessions_controller:
class SessionsController < ApplicationController
respond_to :json
def new
#empty because no underlying model
end
def create
#user = User.find_by_email(params[:user][:email]) #when JSON: { "user" : { "email":"asdf@asdf.at", "password":"asdf" }}
user = User.find_by_email(params[:email]) #when JSON: { "email":"asdf@asdf.at", "password":"asdf" }
respond_to do |format|
if user && user.authenticate(params[:password]) #because user has_secure_password
session[:user_id] = user.id
format.html { redirect_to images_path, notice: "Login successful!" }
format.json { render :json => {:success => true,
:info => "Logged in",
:data => { } } }
else
format.html { flash.now.alert = "Wrong email or password"
render "new" }
format.json { render :json => {:success => false, :info => "Wrong email or password" } }
end
end
end
def destroy
session[:user_id] = nil
respond_to do |format|
format.html { redirect_to root_path, notice: "Logout successful!" }
format.json { render :json => {:success => true,
:info => "Logged out",
:data => { } } }
end
end
end
rake routes:
root / pages#home
new_image GET /images/new(.:format) images#new
images GET /images(.:format) images#index
image GET /images/:id(.:format) images#show
POST /images(.:format) images#create
edit_image GET /images/:id/edit(.:format) images#edit
PUT /images/:id(.:format) images#update
image DELETE /images/:id(.:format) images#destroy
users POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
login GET /login(.:format) sessions#new
sessions POST /sessions(.:format) sessions#create
logout DELETE /logout(.:format) sessions#destroy
application_controller:
class ApplicationController < ActionController::Base
protect_from_forgery
def current_user
if session[:user_id]
@current_user ||= User.find(session[:user_id])
end
end
def user_signed_in?
current_user.present?
end
helper_method :user_signed_in?
end
登录后,有效(显示图像也适用于GET method and url http://localhost:3000/images
),我无法使用JSON创建新图像。这是我的客户请求(我使用Chrome的简单REST客户端):
url: http://localhost:3000/images
method: POST
Content-Type: application/json
Accept: application/json
Data: {"image":{ "title":"someTitle","url": "someUrl" }}
响应:
500 Internal Server Error
<h1>Template is missing</h1>
<p>Missing template sessions/new, application/new with {:locale=>[:en], :formats=>[:json], :handlers=>[:erb, :builder, :coffee]}. Searched in:
* "c:/Users/XXX/workspaceRubyOnRails/my_server/app/views"
* "c:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/devise-2.2.4/app/views"
</p>
答案 0 :(得分:1)
似乎您的JSON请求未经过身份验证。因此,Devise会将您发送到登录页面。但是您没有登录页面的JSON版本,因此会出现Missing template sessions/new
错误。
您可以将Cookie与请求一起发送,甚至更好,使用Devise中的token authentication,这样您就可以使用令牌进行身份验证,请执行以下操作:
curl -v -H "Accept: application/json" -H "Content-type: application/json" http://localhost:3000/images?auth_token=<token>
您可以在此处找到一些代码示例:https://github.com/plataformatec/devise/wiki/How-To:-Simple-Token-Authentication-Example
答案 1 :(得分:0)
我认为您需要通过Chrome简单REST客户端进行身份验证 - 您的rails应用程序似乎区分了Chrome本身和其他客户端。
一旦你克服了这个障碍,我会扩大这个答案。