Devise 做用户验证好强大啊,但是想扩展改交互很难啊,求各位大大指条明路
@qige023 其实挺简单的,继承 Devise::XXController
, 然后重写相关的 actions 就可以了。
比如,我在项目中实现 ajax 的注册:
class RegistrationsController < Devise::RegistrationsController
before_filter :update_sanitized_params, if: :devise_controller?
def new
super
end
def create
if bit_enable?
if ! InviteCode.validate_code(params[:code])
render_fail('注册失败', errors: { code: '邀请码不正确或已被使用'} )
return
end
end
@user = User.new(sign_up_params)
if @user.save
flash[:notice] = '注册成功'
sign_up(:user, @user)
if bit_enable?
InviteCode.mark_used(params[:code])
end
render_success
else
render_fail('注册失败', @user)
end
end
end
render_success 定义:
def render_success(msg = nil, data = {})
render :json => {
success: true,
message: msg.to_s
}.merge(data)
end
谢谢,@lyfi2003 这个思路应该可以做好注册的 JSON 返回,但我更想知道怎么扩展 用户 log_in/log_out 的 Devise::SessionController 的行为,比如我自己如果写了一个 SessionsController < Devise::SessionsController 那我怎样构造请求去访问自己的 SessionsController,而不是访问默认的
devise_for :users, path: "user",
:controllers=>{
:sessions => "users/sessions",
:registrations => "users/registrations",
path_names: { sign_in: 'login', sign_up: 'signup'}
在 users/sessions_controller.rb 里
class Users::SessionsController < Devise::SessionsController
def create
# 在这里写自己的实现,覆盖 Devise 的 create 方法
end
end
感谢 @lyfi2003 和@jyootai 大大的无私帮助,这里贴上 本人暂时可用的 Ajax log_in log_out 代码抛砖引玉
这里还有一个问题,现在是可以响应 form post 了,
但是我想 post 的是 JSON 格式(虽然 form post 也可以用,只是处女座完美主义求大大轻喷),但无论我是 用 email,:email,还是用~ ~
~~user[:email] 来做 JSON 对象的 key,device 都识别不了
class Users::SessionsController < Devise::SessionsController
# POST /resource/sign_in
def create
respond_to do |format|
format.html{ super }
format.json do
resource = warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#failure")
return sign_in_and_redirect(resource_name, resource)
end
end
end
# DELETE /resource/sign_out
def destroy
respond_to do |format|
format.html{ super }
format.json do
redirect_path = after_sign_out_path_for(resource_name)
signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name))
code = signed_out ? "S_OK" : "FA_UNKNOWN_ERROR";
render :json => {:code => code, :redirect => redirect_path}
end
end
end
def sign_in_and_redirect(resource_or_scope, resource=nil)
scope = Devise::Mapping.find_scope!(resource_or_scope)
resource ||= resource_or_scope
sign_in(scope, resource) unless warden.user(scope) == resource
respond_to do |format|
format.json {render :json => {:code => "S_OK", :redirect => stored_location_for(scope) || after_sign_in_path_for(resource)}}
format.html {redirect_to root_url}
end
end
def failure
user = User.find_by_email(params[:user][:email])
code = nil
if user != nil
user.valid_password?(params[:user][:password]) ? code : code = "FA_PASSWORD_ERROR"
else
code = "FA_USAR_NOT_EXIT"
end
respond_to do |format|
format.json {render :json => {:code => code}}
end
end
end
JSON POST 方式,device 已经默认支持, example: