我的Rails应用程序使用Devise进行身份验证.它有一个姐妹iOS应用程序,用户可以使用他们用于Web应用程序的相同凭据登录iOS应用程序.所以我需要某种API进行身份验证.
这里有很多类似的问题指向本教程,但它似乎token_authenticatable已经过时了,因为该模块已从Devise中删除,并且某些行会抛出错误.(我正在使用Devise 3.2.2.)我试图根据那个教程(和这个教程)推出自己的教程(但是这个),但我对它没有100%的信心 - 我觉得我可能会有一些东西被误解或错过了.
首先,按照这个要点的建议,我authentication_token在我的users表中添加了一个text属性,以及以下内容user.rb:
before_save :ensure_authentication_token
def ensure_authentication_token
if authentication_token.blank?
self.authentication_token = generate_authentication_token
end
end
private
def generate_authentication_token
loop do
token = Devise.friendly_token
break token unless User.find_by(authentication_token: token)
end
end
Run Code Online (Sandbox Code Playgroud)
然后我有以下控制器:
api_controller.rb
class ApiController < ApplicationController
respond_to :json
skip_before_filter :authenticate_user!
protected
def user_params
params[:user].permit(:email, :password, :password_confirmation)
end
end
Run Code Online (Sandbox Code Playgroud)
(注意我application_controller有这条线before_filter :authenticate_user!.)
API/sessions_controller.rb
class Api::SessionsController < Devise::RegistrationsController
prepend_before_filter :require_no_authentication, :only …Run Code Online (Sandbox Code Playgroud) 在RSpec中,it_behaves_like和之间有什么区别include_examples?
该文件说:
include_examples- 包括当前背景下的示例
it_behaves_like "name"- 在嵌套上下文中包含示例
但这究竟意味着什么呢?将一个替换为另一个似乎对我的测试是通过还是失败没有影响.在某些情况下,是否有理由偏爱另一个?
另外,是it_should_behave_like和it_behaves_like刚才的同义词?
我正在浏览充满这样代码的代码库:
if let Some(i) = func1() {
if let Some(j) = func2(i) {
if let Some(k) = func3(j) {
if let Some(result) = func4(k) {
// Do something with result
} else {
println!("func 4 returned None");
}
} else {
println!("func 3 returned None");
}
} else {
println!("func 2 returned None");
}
} else {
println!("func 1 returned None");
}
Run Code Online (Sandbox Code Playgroud)
这是一个愚蠢的、简化的例子,但一般模式是:
Option.None)传递给下一个函数。Some,则返回的最终值将用于某些用途。None,则执行停止并记录某种错误 …我有一个新的Rails 4应用程序,它不包含自定义Javascript - 文件夹app/assets/javascripts,lib/assets/javascripts并且vendor/assets/javascripts都是空的(除了app/assets/javascripts/application.js).
当我点击应用程序时,我一直jquery-ujs has already been loaded!在JS控制台中收到错误.每次我点击"后退"按钮时都会发生这种情况,有时当我点击正常链接时(虽然我无法让它始终如一地发生).
application.js中:
//= require jquery
//= require jquery_ujs
//= require twitter/bootstrap
//= require turbolinks
//= require_tree .
Run Code Online (Sandbox Code Playgroud)
当我从application.js中删除turbolinks时,我不再收到错误...所以turbolinks似乎是罪魁祸首.
这是turbolinks的错误,还是我做错了什么?
这是我的Gemfile:
source 'https://rubygems.org'
ruby '2.0.0'
gem 'rails', '4.0.0'
gem 'active_model_serializers'
gem 'aws-sdk'
gem 'bootstrap-sass-rails'
gem 'coffee-script-source', '1.5.0'
gem 'coffee-rails', '~> 4.0.0'
gem 'devise'
gem 'factory_girl_rails', '4.1.0'
gem 'figaro'
gem 'font-awesome-sass-rails'
gem 'jbuilder', '~> 1.2'
gem 'jquery-rails'
gem 'paperclip'
gem 'paperclip-meta', github: …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用构建一个简单的登录系统<form method="post">.我的笔记本电脑上的MAMP一切正常,但是当我将脚本上传到服务器(Windows)时,它无效; 好像$ _POST数组是空的.
我评论了除了骨头之外的一切,但它仍然不起作用.
index.php文件:
<form id="login-form" method="POST" action="_scripts/check_login.php">
Email Address
<input name="login-email" type="text" id="login-email">
Password
<input name="login-password" type="text" id="login-password">
<input type="submit" name="Submit" id="login-button" value="Login">
</form>
Run Code Online (Sandbox Code Playgroud)
_scripts/check_login.php :(除了一些var_dump以外,我已删除了所有内容以进行调试)
var_dump($_POST);
$loginEmail = trim($_POST['login-email']);
echo '<br>';
$loginPassword = ($_POST['login-password']);
var_dump($loginEmail);
echo '<br>';
var_dump($loginPassword);
Run Code Online (Sandbox Code Playgroud)
当我提交表单时,无论我在文本字段中添加什么,我都会看到:
array(0) { }
string(0) ""
NULL
Run Code Online (Sandbox Code Playgroud)
如果我在上面两个文件中将"post"的所有实例更改为"get",一切正常.但我不想用get.(如果我使用method ="post"提交表单,则$ _REQUEST不起作用).
注意,这一切都可以在localhost上运行,但不能在服务器上运行(运行Windows.)所以这似乎是服务器的问题,但我不知道是什么.你可以在这里看到PHPInfo:http://brailleapps.org/phpinf0.php
有任何想法吗?
编辑:解决了!见下文.
假设我有一个模型User和一个序列化程序UserSerializer < ActiveModel::Serializer,以及一个如下所示的控制器:
class UsersController < ApplicationController
respond_to :json
def index
respond_with User.all
end
end
Run Code Online (Sandbox Code Playgroud)
现在,如果我访问,/users我将得到一个如下所示的JSON响应:
{
"users": [
{
"id": 7,
"name": "George"
},
{
"id": 8,
"name": "Dave"
}
.
.
.
]
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我想在JSON响应中包含一些与任何特定用户无关的额外信息,该怎么办?例如:
{
"time": "2014-01-06 16:52 GMT",
"url": "http://www.example.com",
"noOfUsers": 2,
"users": [
{
"id": 7,
"name": "George"
},
{
"id": 8,
"name": "Dave"
}
.
.
.
]
}
Run Code Online (Sandbox Code Playgroud)
这个例子是设计的,但它是我想要实现的很好的近似.活动模型序列化器可以实现这一点吗?(也许通过子类化ActiveModel::ArraySerializer?我无法弄明白).如何添加额外的根元素?
我一直在努力为我的用户注册页面编写自动化测试.将通过Stripe向用户收取定期订阅费用.他们在同一表格上输入他们的基本信息(电子邮件,密码等)和他们的信用卡详细信息,然后发生以下流程:
Stripe::Customer对象,添加正确的订阅并使用Stripe的ruby gem等对其进行充电.所有这一切都很好......除了我无法弄清楚如何测试它.测试步骤#4很容易,因为它发生在服务器端,所以我可以使用类似VCR的gem来模拟Stripe调用.
第一步是给我带来麻烦的.我试图使用两者puffing-billy和stripe-ruby-mock宝石测试这个,但没有任何作用.这是我自己的javascript(简化):
var stripeResponseHandler = function (status, response) {
console.log("response handler called");
if (response.error) {
// show the errors on the form
} else {
// insert the token into the form so it gets submitted to the server
$("#credit_card_token").val(response.id);
// Now submit the form.
$form.get(0).submit();
}
}
$form.submit(function (event) {
// Disable the submit button to prevent repeated clicks
$submitBtn.prop("disabled", true);
event.preventDefault();
console.log("creating token...");
Stripe.createToken(
// Get …Run Code Online (Sandbox Code Playgroud) 我有一个ActiveSupport :: Concern模块,看起来大致如下:
module MyModel
module Acceptance
extend ActiveSupport::Concern
included do
enum status: [:declined, :accepted]
end
def declined!
self.status = :declined
# some extra logic
self.save!
end
def accepted!
self.status = :accepted
# some extra logic
self.save!
end
end
end
Run Code Online (Sandbox Code Playgroud)
这只会被包含在ActiveRecord类中,因此使用enum.基本上,我正在用我自己的一些额外的自定义逻辑来覆盖declined!和accepted!创建的方法ActiveRecord::Enum.enum.
问题是,这不起作用,因为当我调用@model.declined!它时只需调用原始实现declined!并忽略我的自定义方法.
看起来我的自定义方法在运行包含块之前被包含在调用类中- 这意味着我的自定义方法被定义的方法覆盖enum,而不是相反.
在这种特殊情况下有一些简单的解决方法(例如,我可以将调用enum移回到包含类并确保它在线上include MyModel::Acceptance,但我想知道是否有一种方法可以解决这个问题,同时将它保存在同一个模块中.
有没有办法可以在included定义实例方法中调用类方法,然后在同一个Concern模块中覆盖该实例方法?
ruby overriding ruby-on-rails activesupport activesupport-concern
我正在尝试使用官方的aweber gem将我的Rails应用程序与Aweber通过OAuth集成.
如果我在Rails控制台中关注他们的流程,我可以获得访问令牌,没有问题:
oauth = AWeber::OAuth.new(ENV["AWEBER_CONSUMER_KEY"], ENV["AWEBER_CONSUMER_SECRET"])
puts oauth.request_token.authorize_url
# => https://auth.aweber.com/1.0/oauth/authorize?oauth_token=xxxxxxxxxxxxxx
Run Code Online (Sandbox Code Playgroud)
然后我访问该URL,输入我的凭据,获取验证码,然后返回rails控制台:
oauth.authorize_with_verifier 'xxxxxx'
# => #<OAuth::AccessToken>
Run Code Online (Sandbox Code Playgroud)
成功!
问题是,我想在现实世界中这样做,而不仅仅是在控制台上,这意味着我的Ruby代码需要分解为两个单独的操作.首先,控制器操作重定向到Aweber的Oauth页面:
def aweber
oauth = AWeber::OAuth.new(ENV["AWEBER_CONSUMER_KEY"], ENV["AWEBER_CONSUMER_SECRET"])
redirect_to oauth.request_token(oauth_callback: "http://127.0.0.1:3000/auth/aweber/callback").authorize_url
end
Run Code Online (Sandbox Code Playgroud)
然后是用户输入其凭据并被重定向后获取访问令牌的操作:
def aweber_callback
oauth = AWeber::OAuth.new(ENV["AWEBER_CONSUMER_KEY"], ENV["AWEBER_CONSUMER_SECRET"])
oauth.authorize_with_verifier(params[:oauth_verifier])
end
Run Code Online (Sandbox Code Playgroud)
当我这样做时,最后一行(authorize_with_verifier)总是提升#<OAuth::Unauthorized: 401 Unauthorized>.
似乎问题是我正在初始化oauth变量两次,这意味着我有两个不相关的实例AWeber::Oauth...而且只有生成authorize_url的AWeber :: Oauth实例才能获得访问令牌.但我无法在两者中获得相同的实例aweber_callback,aweber因为我正在处理两个完全不同的线程和控制器实例.
当我检查时oauth,我可以看到内部变量oauth.request_token.params["oauth_token"]并且oauth.request_token.params["oauth_token_secret"]每个变量都不同oauth,我猜这是导致问题的原因.我可以oauth_token从params(params[:oauth_token])获得'正确' ,但我无法弄清楚如何获得正确的oauth_token_secret(更不用说手动设置这样的实例变量感觉非常 hacky并且可能不是最好的方法.)
如何生成访问令牌?
说我有机型User和Post,用户has_many的职位和岗位belongs_to的用户.
当我写一个规范时Post,我的第一直觉是写这样的东西:
before do
@user = FactoryGirl.create :user
@post = @user.posts.new(title: "Foo", content: "bar)
end
... tests for @post go here ...
Run Code Online (Sandbox Code Playgroud)
但这将创建一个新的用户 - 命中数据库 - 对于每一次测试,这将减慢速度.有没有更好的方法来加快我的测试速度并避免频繁击中数据库?
据我所知,我不能使用FactoryGirl.build :user因为,即使它不会打到数据库,关联也无法正常工作,因为@user没有ID,所以@post.user不会工作(它返回nil.)
我可以使用FactoryGirl.build_stubbed :user哪个创建了一个"假@user持有" ,它有一个ID,但@post.user仍然返回nil.当我测试与协会有关的事情时,是否build_stubbed有任何实际优势build?
我想我可以使用build_stubbed存根,@post.user所以它返回@user...有什么理由这可能是个坏主意吗?
或者我应该使用create并接受速度命中?
我能想到的唯一另一种选择是在一个before(:all)块中设置@user 似乎是一个坏主意.
以简洁明了的方式编写这类测试的最佳方法是什么,避免进行过多的数据库查询?
ruby ×4
rspec ×2
activemodel ×1
api ×1
aweber ×1
capybara ×1
devise ×1
factory-bot ×1
forms ×1
javascript ×1
jquery ×1
json ×1
oauth ×1
omniauth ×1
overriding ×1
php ×1
poltergeist ×1
post ×1
readability ×1
refactoring ×1
rust ×1
security ×1
testing ×1
turbolinks ×1
unit-testing ×1