使用gem rucaptcha
目标
- 学习如何阅读README并安装Gem。
- 依照Rucaptcha的README操作,并自定义devise的登入登出,实现注册/登入时需要填入验证码。
- https://github.com/huacnlee/rucaptcha
- https://github.com/huacnlee/rucaptcha/wiki/Working-with-Devise
步骤
Step 1
依照README步骤,将rucaptcha加到Gemfile:
+ gem 'rucaptcha'
创建档案,输入指令如下:
touch config/initializers/rucaptcha.rb
并填入如下内容
RuCaptcha.configure do
# Color style, default: :colorful, allows: [:colorful, :black_white]
# self.style = :colorful
# Custom captcha code expire time if you need, default: 2 minutes
# self.expires_in = 120
# [Requirement/重要]
# Store Captcha code where, this config more like Rails config.cache_store
# default: Read config info from `Rails.application.config.cache_store`
# But RuCaptcha requirements cache_store not in [:null_store, :memory_store, :file_store]
# 默认:会从 Rails 配置的 cache_store 里面读取相同的配置信息,用于存储验证码字符
# 但如果是 [:null_store, :memory_store, :file_store] 之类的,你可以通过下面的配置项单独给 RuCaptcha 配置 cache_store
self.cache_store = :mem_cache_store
end
Step 2
自定义devise,参考rucaptcha的wiki教程
首先先把devise的controller叫出来:
rails g devise:controllers users
自定义registration的controller如下:
app/controllers/users/registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
def create
build_resource(sign_up_params)
if verify_rucaptcha?(resource) && resource.save
yield resource if block_given?
if resource.persisted?
if resource.active_for_authentication?
set_flash_message! :notice, :signed_up
sign_up(resource_name, resource)
respond_with resource, location: after_sign_up_path_for(resource)
else
set_flash_message! :notice, :"signed_up_but_#{resource.inactive_message}"
expire_data_after_sign_in!
respond_with resource, location: after_inactive_sign_up_path_for(resource)
end
else
clean_up_passwords resource
set_minimum_password_length
respond_with resource
end
else
clean_up_passwords resource
respond_with resource
end
end
...(略)
end
把devise的view叫出来,在终端输入:
rails g devise:views users
自定义registration的view如下:
app/views/users/registrations/new.html.erb
...(略)
<div class="form-inputs">
<%= f.input :email, required: true, autofocus: true %>
<%= f.input :password, required: true, hint: ("#{@minimum_password_length} characters minimum" if @minimum_password_length) %>
<%= f.input :password_confirmation, required: true %>
+ <%= rucaptcha_image_tag(alt: 'Captcha') %>
+ <%= rucaptcha_input_tag(class: 'form-control', placeholder: '请输入验证码') %>
</div>
...(略)
修改routes如下:
config/routes.rb
Rails.application.routes.draw do
...(略)
- devise_for :users
+ devise_for :user, controllers: {
+ passwords: 'users/passwords',
+ registrations: 'users/registrations',
+ sessions: 'users/sessions'
+ }
...(略)
end
到http://localhost:3000/user/sign_up 尝试注册一个新的帐号,但验证图片没有显示出来:
右键点破掉的图片,到这个链结 http://localhost:3000/rucaptcha/
出现如下报错:
安装gem dalli
bundle install
重启rails s
再次注册,但填写验证码正确还是无法注册的话,检查rails s的logs是否有类似如下的错误:
如有的话,请依照如下步骤排错:
在终端输入
brew install memcached
brew services start memcached
重启rails s即可。
Step 3
一样的步骤修改登入
app/controllers/users/sessions_controller.rb
class Users::SessionsController < Devise::SessionsController
prepend_before_action :valify_captcha!, only: [:create]
def valify_captcha!
unless verify_rucaptcha?
redirect_to new_user_session_path, alert: t('rucaptcha.invalid')
return
end
true
end
...(略)
end
app/views/users/sessions/new.html.erb
...(略)
<div class="form-inputs">
<%= f.input :email, required: false, autofocus: true %>
<%= f.input :password, required: false %>
<%= f.input :remember_me, as: :boolean if devise_mapping.rememberable? %>
+ <%= rucaptcha_image_tag(alt: 'Captcha') %>
+ <%= rucaptcha_input_tag(class: 'form-control', placeholder: '请输入验证码') %>
</div>
...(略)
到 http://localhost:3000/user/sign_in 测试看看
对以上操作有疑问,可参考YY repo:
https://github.com/yungyuan/jdstore/tree/rucaptcha
Step 4
请自己实际操作找回密码
提示:更改以下两个档案
app/controllers/users/passwords_controller.rb
app/views/users/passwords/new.html.erb
Step 5 Rucaptcha + heroku
如要上传到heroku,请依照如下设置操作:
git checkout -b rucaptcha-heroku
在heroku上启用memcachier这个服务:
heroku addons:create memcachier:dev
移除原来的rucaptcha.rb
mv config/initializers/rucaptcha.rb config/initializers/rucaptcha.rb.temp
并在 config/environments/production.rb 修改如下(最下面end以上找地方加即可):
Rails.application.configure do
... (略)
+ config.cache_store = :dalli_store,
+ (ENV["MEMCACHIER_SERVERS"] || "").split(","),
+ {:username => ENV["MEMCACHIER_USERNAME"],
+ :password => ENV["MEMCACHIER_PASSWORD"],
+ :failover => true,
+ :socket_timeout => 1.5,
+ :socket_failure_delay => 0.2,
+ :down_retry_delay => 60
+ }
... (略)
end
保存修改
git add .
git commit -m "change config for rucaptcha/dalli on heroku"
上传到heroku
git push heroku rucaptcha-heroku:master
具体作法可参考repo: https://github.com/yungyuan/jdstore/tree/rucaptcha-heroku
备注:如此一来,本地上的rucaptcha将无法使用,所以这个设置只能适用heroku。要两边都能适用,请依照JDStore部署到heroku的类似方式修改。
Updated over 5 years ago