我已经创建了一个rails-api应用程序并继续使用令牌认证来保护它.
我设置了一个before_filter调用使用的方法authenticate_or_request_with_http_token.一切正常,但是,当身份验证不正确时,我得到一个HTML响应.
如何定义响应的格式?
before_filter :restrict_access
private
def restrict_access
authenticate_or_request_with_http_token do |token, options|
check_token token
end
end
def check_token(token)
Session.exists?(access_token: token)
end
Run Code Online (Sandbox Code Playgroud) 我想使用rails-api gem special来创建仅限API的应用程序.为了提供身份验证机制,我想使用Railscasts#352中描述的内置authenticate_or_request_with_http_token方法,但此方法在此处缺失.
有没有人对rails-api gem 有经验?
PS我可以看到这种方法,但是这个生产准备好了吗?
我实际上正在使用一个使用Rails 4的API.Content-Type如果客户端没有在Content-Type头文件中指定媒体类型,我想将请求设置为JSON .
为了获得该行为,我尝试before_action在我的添加中添加以下内容ApplicationController:
def set_request_default_content_type
request.format = :json
end
Run Code Online (Sandbox Code Playgroud)
在我的RegistrationsController#create方法中,我有一个断点来检查一切是否正常.好吧,request.format诀窍不起作用,尽管设置的值application/json似乎控制器(或Rails内部)不会将接收到的请求的Content-Type视为JSON.
我使用以下正文进行了POST请求(并且没有Content-Type):
{"user" : {"email":"foobar@mail.net","password":"foobarfoo"}}
Run Code Online (Sandbox Code Playgroud)
通过Pry调试我看到:
[2] api(#<V1::RegistrationsController>) _ request.format.to_s
=> "application/json"
[3] api(#<V1::RegistrationsController>) _ params
=> {
"action" => "create",
"controller" => "v1/registrations"
}
Run Code Online (Sandbox Code Playgroud)
这意味着Rails没有使用配置的request.format考虑我的请求Mime::JSON,而是使用Mime::ALL,因此它没有解析请求的JSON主体.:(
我正在使用rails-api构建一个公共的json api.
我想回应OPTIONS HTTP方法以利用跨源资源共享.
我这样做:
headers['Access-Control-Allow-Methods'] = 'POST, PUT, DELETE, GET, OPTIONS'
Run Code Online (Sandbox Code Playgroud)
它可以工作,但有些URL不支持所有HTTP方法.在那些情况下,我撒谎.
我不想为每个URL配置Access-Control-Allow-Methods.
有没有办法根据我的路线响应Access-Control-Allow-Methods?
我有一个在Rails中开发的应用程序,我试图在HTTP标头中查看属性.
有没有办法阅读这些属性?它们存放在哪里?
有人提到过request.headers.它是否正确?我无法在此数组中看到任何属性.
我正在构建一个ember.js应用程序,我挂了认证.json休息后端是rails.每个请求都使用会话cookie(warden)进行身份验证.
当用户首次导航到应用程序根轨道重定向到登录页面时.会话授权后,将加载ember.js应用程序.加载后,ember.js应用程序使用ember-data RESTadapter和会话进行授权,向后端发出请求.
问题是会话将在预定的时间后过期.很多时候,当发生这种情况时,仍然会加载ember.js应用程序.因此,对后端的所有请求都会返回401 {not autorized}响应.
为了解决这个问题,我认为每次从服务器返回401 {not autorized}响应时,ember.js应用程序都需要通过登录模式通知用户.
有谁知道如何监听401 {not autorized}响应并允许用户重新登录而不会丢失任何更改或状态.
我见过其他方法,如令牌授权,但我担心安全问题.
有人有解决这个问题的工作方法吗?
我正在使用rails-api gem来构建Web服务,并希望使用RSpec测试我的API.无论HTTP方法如何,我发出的每个请求都将CONTENT_TYPE标头设置为"application/x-www-form-urlencoded".在我尝试在我的控制器中使用wrap_parameters并且它对params哈希没有任何影响之前,这不是一个真正的问题:
class ApplicationController < ActionController::API
include ActionController::ParamsWrapper
end
class ProjectsController < ApplicationController
wrap_parameters :project, include: [:name]
# ...
end
Run Code Online (Sandbox Code Playgroud)
这个hack不再有效(@request是nil),而且我发现的其他Stack Overflow帖子都没有.
如果我在RSpec测试中提出以下请求:
put "/projects/1.json", {name: 'Updated Project 1'}
Run Code Online (Sandbox Code Playgroud)
并在我的控制器中放置一个调试器:
(rdb:1) p params
{ "name"=>"Updated Project 1",
"action"=>"update",
"controller"=>"projects",
"id"=>"5539bbd9-010c-4cfb-88d3-82dadbc99507",
"format"=>"json"
}
(rdb:1) p request.content_type
"application/x-www-form-urlencoded"
Run Code Online (Sandbox Code Playgroud)
我希望看到类似于params hash的东西(注意添加项目键):
{ "name"=>"Updated Project 1",
"action"=>"update",
"controller"=>"projects",
"id"=>"5539bbd9-010c-4cfb-88d3-82dadbc99507",
"format"=>"json",
"project" => {"name" => "Updated Project 1"}
}
Run Code Online (Sandbox Code Playgroud)
是否可以仅使用RSpec设置内容类型标题?或者我是否必须使用机架/测试来实现此功能?
我在我的项目中使用rails_api gem.我想添加会话管理进行身份验证,但似乎会话无效.这是我的配置config/initializer/session_store.rb:
Pmcapi::Application.config.session_store :cookie_store, {
key: '_pmcapi_session',
expire_after: 1.hour
}
Run Code Online (Sandbox Code Playgroud)
我添加config.api_only = false了application.rb(将cookie会话存储添加回Rails API应用程序)
在我session_controller,我添加了会话来存储令牌
# session_controller.rb
def create
#just to generate new token
user.reset_sso_token!
session[:token] ||= user.sso_token
self.current_user = user
redirect_to root_path
end
Run Code Online (Sandbox Code Playgroud)
在进入时application_controller,我想访问,session[:token]但结果是nil:
# application_controller.rb
def authenticate_user!
#puts("User Authentication")
#puts(request.authorization)
#puts(request)
@user = User.authenticate_with_token(session[:token])
#head :unauthorized unless @user.present?
redirect_to sign_in_path if @user.nil?
end
Run Code Online (Sandbox Code Playgroud) 我有一个Rails 3引擎,可以为大约20个控制器公开API路由.这些控制器代表了不同嵌套级别的几种不同资源,并且有超过500种rspec测试.API在v1上使用名称空间和基于版本标头的路由约束进行版本控制,默认为v1.这是很多博客文章中描述的版本控制系统,似乎是最佳实践.
这些博客文章中没有描述的是您如何实际管理推出新版本.我必须对单个控制器的输出进行重大更改.此更改通过更改其中一个JSON值的结构来影响对象的JSON响应.这将导致该控制器的索引,显示和编辑视图中断.
很明显,我可以将所有内容复制app/api/v1到app/api/v2[1].然后,我可以对我的新v2序列化器进行单一更改.我现在已经为API的第2版获得了大量重复代码,几乎没有任何更改.我需要在两个地方维护代码.我可能不得不让我的整个rspec套件在版本2控制器以及版本1控制器上运行,并对v2序列化器进行一些额外的测试.这听起来像一个可怕的想法.对于从v1控制器继承的v1命名空间中的每个未更改的控制器,我们可以有一些stub v2控制器.这听起来也不是很好.
我能想到的最好的选择是在我的v2 API中有一个单独的控制器(在这种情况下可能只是一个串行器),有一些路由魔术可以检查是否存在所需版本的控制器并通过以前的版本回退直到找到一个.序列化程序版本也应具有类似的魔力,以检查此版本是否存在,并在找到之前回退.这引入了最少的额外代码,并且不会立即使我的测试套件的持续时间翻倍.它需要能够将函数直接插入到rails路由逻辑中,然后才能为我丢失的v2控制器返回404.可能我可以根据文件系统分析所有控制器的命名空间,并在rails启动时使用回退生成路由,但是很难明确地从先前版本的API中删除路由.
似乎我们需要继续为每个非附加功能/输出格式进行更改,直到每个先前版本被弃用和删除为止.我们有一个额外的未发布的API,包含约4000个控制器,涵盖~4000个规格.当我们开始从外部记录并发布这些内容时会发生什么?
除了按照我们发布功能的速率批量处理API更改之外,其他人如何管理?上面的想法是否可行?有没有更好的办法?
[1]问题一.我们使用ActiveModel :: Serializers来生成JSON响应.ActiveModel :: Serializers 不支持API版本控制,尽管似乎有一种方法可以使用ruby魔法来选择正确的类.
我正在开发 Rails RESTful API,并在某些端点上设置了版本控制功能。我有一个类ApiVersion,负责根据初始化时传递给它的参数确定要渲染哪些控制器。
类定义如下:
class ApiVersion
attr_reader :version, :default
def initialize(version, default = false)
@version = version
@default = default
end
# check whether version is specified or is default
def matches?(request)
check_headers(request.headers) || default
end
private
def check_headers(headers)
# check version from Accept headers; expect custom media type 'suits'
accept = headers[:accept]
accept&.include?("application/vnd.suits.#{version}+json")
end
end
Run Code Online (Sandbox Code Playgroud)
这些请求工作得很好,但是当我运行时,rubocop -A我收到一条错误消息:
Style/OptionalBooleanParameter: Use keyword arguments when defining method with boolean argument.
def initialize(version, default = false)
Run Code Online (Sandbox Code Playgroud)
我在互联网上搜索了如何修复此类错误并得到了一些有趣的想法,但这些想法不适用于我的情况。例如,我发现一篇文章说我应该交替def …