OAuth APIプロバイダーとして機能しているRoR 3.0 Webアプリケーションがあります。APIでAPIコンシューマーに正しいHTTPエラーコードを返したいのですが、どうすればよいですか?
以下に例を示します。
def destroy_oauth
@item = Item.find(params[:id])
if([email protected]? && @item.user_id == current_user.id)
@item.destroy
respond_to do |format|
format.js
format.xml
end
else
raise ActionController::RoutingError.new('Forbidden')
end
end
したがって、エラーが発生した場合、Forbidden 403コードを返そうとしています。それでも、これを実行すると、常に404 Not Foundが返されます。正しいコードを返すにはどうすればよいですか?
または、これは何らかの形でウェブサーバーの設定可能なものですか?
ページを正しい状態でレンダリングする必要があります。
render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
ステータスコードを与えているだけで、本文がない場合、便利な方法は
head 403
このメソッドは、次のようなステータスコードのシンボル名も受け入れます。
head :forbidden
ActionController :: Head docs によると、アクションでこのパターンを使用するだけです
return head([status]) if/unless [some condition here]
例:
return head(:gone) if @record.deleted?
return head(:forbidden) unless @user.owns?(@record)
return
は、アクション内の残りのコードが実行されないようにするために使用されます。
まあ、使用できます
:status =>500
しかし、デフォルトではRailsはエラータイプのレンダリング自体を処理します。
エラーのデフォルトページはパブリックディレクトリにあります。 500.html、404.htmlなど。
ここには2つの問題があると思います。1つ目は、@item = Item.find(params[:id])
行が404を上げており、実行が意図した場所(if
ステートメント)に到達しないことです。 2番目は、例外を発生させて、決してキャッチしないことです。試してください:
def destroy_oauth
begin
@item = Item.find(params[:id])
if([email protected]? && @item.user_id == current_user.id)
@item.destroy
respond_to do |format|
format.js
format.xml
end
else
raise ActionController::RoutingError.new('Forbidden')
end
rescue ActiveRecord::ResourceNotFound
redirect_to :action => 'not_found', :status => 404 # do whatever you want here
rescue ActionController::RoutingError
redirect_to :action => 'forbidden', :status => 403 # do whatever you want here
end
end
これらの行に沿ったものですが、APIを作成していることにも言及しているため、エラーを救出するときにxml
エラー情報をレンダリングすることができます。何かのようなもの:
# in application_controller.rb
rescue_from ActionController::RoutingError, :with => :render_forbidden_error
private
def render_forbidden_error(e)
render :status => e.status, :xml => e
end
幸運を。うだち。