Last active
April 14, 2018 09:42
-
-
Save Lupeipei/d8fcb48b588c2c0fb217052baa482eed to your computer and use it in GitHub Desktop.
rails对接微信后完成手机验证
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="http:res.wx.qq.com/open/js/jweixin-1.2.0.js"></script> | |
<%= wechat_config_js debug: false, api: %w(closeWindow) -%> | |
<style> | |
.disappear { | |
display: none; | |
} | |
</style> | |
<% unless @user.errors.empty? %> | |
<div id="error_dialog"> | |
<div class="weui-mask"></div> | |
<div class="weui-dialog"> | |
<div class="weui-dialog__hd"><strong class="weui-dialog__title">Demo</strong></div> | |
<ul> | |
<% @user.errors.messages.values.flatten.each do |error| %> | |
<div class="weui-dialog__bd"><%= error %></div> | |
<% end %> | |
</ul> | |
<div class="weui-dialog__ft"> | |
<a href="" id="error_dialog_button" class="weui-dialog__btn weui-dialog__btn_primary">确定</a> | |
</div> | |
</div> | |
</div> | |
<% end %> | |
<div class="weui-msg"> | |
<div class="weui-msg__text-area"> | |
<h1 class="weui-msg__title">会员登录</h1> | |
</div> | |
</div> | |
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %> | |
<div class="weui-cells_title"> 请输入您的手机号,绑定会员</div> | |
<div class="weui-cells weui-cells_form"> | |
<div class="weui-cell weui-cell_vcode" style="height: 45px;"> | |
<div class="weui-cell__hd"> | |
<%= f.label :手机号, class: 'weui-label' %> | |
</div> | |
<div class="weui-cell__bd weui-cell_primary"> | |
<%= f.text_field :phone, class: 'weui-input',id: 'user_cellphone',type: "tel", placeholder: '请输入手机号' %> | |
</div> | |
<div class="weui-cell__ft"> | |
<input type="button" style="background: none; border: none " value="获取验证码" class="weui-vcode-btn" id="token_btn">获取验证码</input> | |
</div> | |
</div> | |
<div class="weui-cell weui-cell_vcode" style="height: 45px;"> | |
<div class="weui-cell__hd"> | |
<%= f.label :验证码, class: 'weui-label' %> | |
</div> | |
<div class="weui-cell__bd weui-cell_primary"> | |
<%= f.text_field :token, class:"weui-input", type: "number", placeholder: "请输入验证码" %> | |
</div> | |
</div> | |
</div> | |
<label for="weuiAgree" class="weui-agree"> | |
<input id="weuiAgree" type="checkbox" checked="checked" class="weui-agree__checkbox"> | |
<span class="weui-agree__text"> | |
获得您的公开信息(昵称,头像等) | |
</span> | |
</label> | |
<div class="weui-btn-area"> | |
<%= f.submit "确认", class: 'weui-btn weui-btn_primary' %> | |
<a href="javascript:wx.closeWindow();" class="weui-btn weui-btn_plain-default">关闭</a> | |
</div> | |
<% end %> | |
<%= content_for :javascripts do %> | |
<script> | |
(function(){ | |
//手机验证码 | |
var CELLPHONE_RE = /^1[3|4|5|6|7|8][0-9]{9}$/; | |
var token_wait = 60, token_interval; | |
var $token_btn = $('#token_btn'); | |
$token_btn.click(function () { | |
var $this = $(this), cellphone = $('#user_cellphone').val(); | |
$.ajax({ | |
url: "/phone_tokens?phone=" + cellphone, | |
method: 'post', | |
beforeSend: function () { | |
if (!CELLPHONE_RE.test(cellphone)) { | |
$("#messages").text("手机号码格式错误,请重填!"); | |
$("#alert_message").show(); | |
$('#user_cellphone').val(""); | |
return false; | |
} | |
$this.attr('value',"已发送").prop('disabled', true); | |
}, | |
success: function (data) { | |
if (data.status == 'error') { | |
alert(data.message); | |
$token_btn.attr('value','获取验证码').prop('disabled', false); | |
}else if(data.status == 'repeated'){ | |
$("#messages").text("您的手机号已经验证过,无需验证"); | |
$("#alert_message").show(); | |
}else | |
{ | |
$token_btn.attr('value','已发送').prop('disabled', true); | |
$this.trigger('start_token_timer'); | |
} | |
} | |
}) | |
}) | |
.on('start_token_timer', function () { | |
token_interval = setInterval(function () { | |
$token_btn.trigger('token_timer'); | |
}, 1000); | |
}) | |
.on('token_timer', function () { | |
token_wait--; | |
if (token_wait <= 0) { | |
clearInterval(token_interval); | |
$token_btn.attr('value','获取验证码').prop('disabled', false); | |
token_wait = 60; | |
} else { | |
$token_btn.attr('value','重新发送 ' + token_wait + ' 秒').prop('disabled', true); | |
} | |
}) | |
})() | |
</script> | |
<% end %> | |
<div style="display: none;" id="alert_message"> | |
<div class="weui-mask"></div> | |
<div class="weui-dialog"> | |
<div class="weui-dialog__hd"><strong class="weui-dialog__title">Demo</strong></div> | |
<div class="weui-dialog__bd" id="messages">提醒信息</div> | |
<div class="weui-dialog__ft"> | |
<a href="" id="alert_message_button" class="weui-dialog__btn weui-dialog__btn_primary">确定</a> | |
</div> | |
</div> | |
</div> | |
<script> | |
$("#error_dialog_button").click(function() { | |
$("#error_dialog").addClass('disappear'); | |
}); | |
$("#alert_message_button").click(function() { | |
$("#alert_message").addClass('disappear'); | |
}); | |
</script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class PhoneToken < ApplicationRecord | |
validates_presence_of :token | |
validates_presence_of :phone | |
def self.add_or_update(phone, token) | |
record = find_by(phone: phone) | |
if record | |
record.update_attributes token: token, expired_at: Time.now + 10.minutes | |
else | |
create phone: phone, token: token, expired_at: Time.now + 10.minutes | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require_relative '../../lib/sms' | |
class PhoneTokensController < ApplicationController | |
before_action :verify_phone_unrepeated | |
def create | |
unless params[:phone] =~ User::CELLPHONE_RE | |
render json: {status: 'error', message: '手机号格式不正确!'} | |
return | |
end | |
if session[:token_created_at] && session[:token_created_at] + 60 > Time.now.to_i | |
render json: {status: 'error', message: '您已经申请过验证码,请60s后再试!'} | |
return | |
end | |
token = sms_send(params[:phone]) | |
PhoneToken.add_or_update params[:phone], token | |
session[:token_created_at] = Time.now.to_i | |
render json: {status: 'ok'} | |
end | |
private | |
def verify_phone_unrepeated | |
phone = User.find_by(phone: params[:phone]) | |
render :json => { status: 'repeated'} if phone.present? | |
end | |
end | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Send | |
module Sms | |
def sms_send(phone) | |
template_code = "your template code" | |
code = rand(100000..999999) | |
template_param = {"code" => code.to_s}.to_json | |
Aliyun::Sms.send(phone, template_code, template_param) | |
code | |
end | |
end | |
end | |
class Object | |
include Send::Sms | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class User < ActiveRecord::Base | |
# Include default devise modules. Others available are: | |
# :confirmable, :lockable, :timeoutable and :omniauthable | |
devise :database_authenticatable, :registerable, | |
:recoverable, :rememberable, :trackable, :validatable, :omniauthable | |
attr_accessor :token | |
CELLPHONE_RE = /^1[3|4|5|6|7|8][0-9]{9}$/ | |
before_validation :set_password | |
validates_presence_of :phone | |
validate :validate_phone, on: :create | |
def self.from_omniauth(auth) | |
where(provider: auth.provider, uid: auth.uid).first_or_initialize do |user| | |
user.nickname = auth.info.nickname | |
user.sex = auth.info.sex | |
user.avatar = auth.info.headimgurl | |
end | |
end | |
def self.new_with_session(params, session) | |
super.tap do |user| | |
if data = session['devise.wechat_data'] | |
user.provider = data['provider'] | |
user.uid = data['uid'] | |
user.nickname = data['info']['nickname'] | |
user.sex = data['info']['sex'] | |
user.avatar = data['info']['headimgurl'] | |
end | |
end | |
end | |
def email_required? | |
false | |
end | |
def is_member? | |
Customer.find_by(phone: phone).present? | |
end | |
private | |
def set_password | |
self.password ||= Devise.friendly_token[0, 20] | |
end | |
def validate_phone | |
if phone.nil? | |
errors.add :base, '手机号不能为空' | |
elsif !PhoneToken.find_by(phone: phone, token: token) | |
errors.add :phone, '手机验证码不正确或者已过期' | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment