2014-12-01 45 views
0

我没有时间去深入探究.6和.7以及.8,以确保我没有错过任何东西,但是今天我决定更新我的应用程序,这个应用程序主要是一些前端工作的API。升级到Rails 4.1.8和我的API损坏

我更新了应用程序到rails 4.1.8,并且在我的规格中出现了很多错误,实际上任何api必须通过验证才会崩溃。

我使用的API控制器有一个名为restrict_api_access方法,完成通过

def restrict_api_access 
    authenticate_or_request_with_http_token do |token, options| 
     @api_key = ApiKey.find_by(api_key: token) 
    end unless current_user 
    end 

现在,您可以登录到应用和管理的事情,在这种情况下,我们仍然使用相同的API,你会访问通过终端或外部应用程序说。所以unless current_user基本上看起来像这样的:

def current_user 
    if (@api_key) 
     @current_user = User.find_by!(id: @api_key.xaaron_users_id) 
    else 
     super 
    end 
    end 

答那么这个当前用户的super基本状态 - 你在或者没有登录。

所以这是失败的设置类似于这样一个测试:

上下文之前 “新建标签” 做 (:每个)做 @tag = FactoryGirl.build(:标签,blog_id:@ blog.id) set_auth_header(@user) 结束

it "should create a tag for a post" do 
    post :create, :blog_id => @blog.id, tag: {name: @tag.name, description: 'asdasddsa'} 
    json = JSON.parse(response.body) 
    expect(json['tag']['name']).to eql @tag.name 
end 

@user设置了别的地方。但我可以向你保证,用户正在被传入并被创建。

另一个有趣的方法,这里是这种方法看起来像:

# Create a random api key 
def create_api_key(user) 
    ApiKey.create!(:xaaron_users_id => user.id, :api_key => SecureRandom.hex(16)) 
end 

# Set authentication headers for the API use 
def set_auth_header(user) 
    key = create_api_key(user) 
    request.env['HTTP_AUTHORIZATION'] = "Token #{key.api_key}" 
end 

你可以看到我们创建与用户的API密钥,然后我们设置请求环境变量有一个API密钥。

所以在4.1.8之前(我在4.1.5上)这个工作正常,所有的测试都会通过生命是隆重的。现在,通过这个特殊的测试,我得到:

1) Api::V1::TagsController Create new tag should create a tag for a post 
    Failure/Error: json = JSON.parse(response.body) 
    JSON::ParserError: 
     757: unexpected token at 'HTTP Token: Access denied. 
     ' 
    # ./spec/controllers/api/v1/tags_controller_spec.rb:112:in `block (3 levels) in <top (required)>' 

基本上我被拒绝访问。我已经通过追踪这对restrict_api_access到行:authenticate_or_request_with_http_token持有,作为一种价值:HTTP Token: Access denied.

有什么在改变4.1.8将是导致我所有的API,它要求通过验证才能打破?

回答

1

你计算你的授权头手动在这里,这可能是错误的:

request.env['HTTP_AUTHORIZATION'] = "Token #{key.api_key}"

有一个ActionController的方法,这是否对你:

request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Token.encode_credentials(key.api_key)

尝试,与其。