安装gem
Gemfile
+ gem 'sorcery'
group :development, :test do
终端执行 $ bundle install
重启 $ rails s
初始化安装
$ rails g sorcery:install
如何安装sorcery提供的子功能
比如下面的重置密码功能,可以参考config/initializers/sorcery.rb文件
$ rails generate sorcery:install reset_password --only-submodules
配置文件/config/initializers/sorcery.rb,这些地方需要配置,将激活功能删除,减少配置的复杂度
user.user_activation_mailer = nil
user.activation_mailer_disabled = true
user.prevent_non_active_users_to_login = false
Sorcery具体使用
sorcery只有针对密码的加密功能,但是没有针对密码的校验和密码一致性的校验。执行上面的模块建立方式:
$ rails g sorcery:install remember_me reset_password user_activation --only-submodules
config/initializers/sorcery.rb参考如上的配置方式。
配置文件
model/user.rb
class User < ApplicationRecord
authenticates_with_sorcery!
attr_accessor :password, :password_confirmation
validates_presence_of :email, message: "邮箱不能为空"
validates :email, uniqueness: true
validates_presence_of :password, message: "密码不能为空",
if: :need_validate_password
validates_presence_of :password_confirmation, message: "密码确认不能为空",
if: :need_validate_password
validates_confirmation_of :password, message: "密码不一致",
if: :need_validate_password
validates_length_of :password, message: "密码最短6位",
minimum: 6,
if: :need_validate_password
private
def need_validate_password
self.new_record? ||
(!self.password.nil? or !self.password_confirmation.nil?)
end
end
app/controllers/users_controller.rb
class UsersController < ApplicationController
def new
@user = User.new
end
#用户注册
def create
@user = User.new(params.require(:user)
.permit(:email, :password, :password_confirmation))
if @user.save
flash[:notice] = '注册成功,请登录'
redirect_to new_session_path
else
render action: :new
end
end
#用户密码修改
def change_password
if current_user.valid_password?(params[:old_password])
current_user.password_confirmation = params[:password_confirmation]
if current_user.change_password!(params[:password])
render json: {status: 'ok', msg: '密码修改成功'}
else
render json: {status: 'error', msg: current_user.errors.messages.values.flatten}
end
else
render json: {status: 'error', msg: '旧密码不正确'}
end
end
#用户发送忘记密码邮件,这里需要对邮件进行配置
def send_forget_password_email
@user = User.find_by(email: params[:email])
if @user
@user.deliver_reset_password_instructions!
render json: {status: 'ok', msg: "重置密码的链接已发送到上面的邮箱"}
else
render json: {status: 'error', msg: '指定邮箱不存在'}
end
end
#密码重置
def reset_password
@user = User.load_from_reset_password_token(params[:token])
if @user
@user.password_confirmation = params[:password_confirmation]
if @user.change_password!(params[:password])
render json: {status: 'ok', msg: '密码修改成功'}
else
render json: {status: 'error', msg: @user.errors.messages.values.flatten}
end
else
render json: {status: 'error', msg: 'token不正确或者已过期'}
end
end
end
app/views/users/new.html.erb
<h1>用户注册</h1>
<div>
<% unless @user.errors.empty? %>
<ul>
<% @user.errors.messages.values.flatten.each do |error| %>
<li><%= error %></li>
<% end -%>
</ul>
<% end -%>
</div>
<%= form_for :user, url: users_path, method: :post, html: { class: 'form-horizontal', id: "user_form"} do |f| %>
<div class="form-group">
<div class="col-lg-12">邮箱 *</div>
<div class="col-lg-12">
<%= f.text_field :email, class: "form-control" %>
</div>
</div>
<div class="form-group">
<div class="col-lg-12">密码 *</div>
<div class="col-lg-12">
<%= f.password_field :password, class: "form-control" %>
</div>
</div>
<div class="form-group">
<div class="col-lg-12">密码确认 *</div>
<div class="col-lg-12">
<%= f.password_field :password_confirmation, class: "form-control" %>
</div>
</div>
<div class="form-group">
<div class="col-lg-12">
<div class="text-center">
<a href="<%= new_session_path %>">登录</a>
</div>
</div>
</div>
<div class="form-group">
<div class="col-lg-12">
<input type="submit" name="create_user_submit" value="创建账户" class="col-xs-12 btn btn-primary">
</div>
</div>
<% end %>
app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
before_action :auth_user, except: [:destroy]
def new
end
def create
#login是sorcery的登录方法
if user = login(params[:email], params[:password])
flash[:notice] = '登陆成功'
redirect_to root_path
else
flash[:notice] = "邮箱或者密码错误"
redirect_to new_session_path
end
end
def destroy
#logout是sorcery的退出方法
logout
flash[:notice] = "退出登陆"
redirect_to root_path
end
private
def auth_user
#logged_in?是sorcery的判断登录方法
if logged_in?
redirect_to root_path
end
end
end
app/views/sessions/new.html.erb
<h1>用户登录</h1>
<%= form_tag sessions_path, method: :post, class: "form-horizontal" do %>
<div class="form-group">
<div class="col-lg-12">邮箱</div>
<div class="col-lg-12">
<%= text_field_tag :email, nil, class: "form-control" %>
</div>
</div>
<div class="form-group">
<div class="col-lg-12">密码</div>
<div class="col-lg-12">
<%= password_field_tag :password, nil, class: "form-control" %>
</div>
</div>
<div class="form-group">
<div class="col-lg-12">
<div class="text-center">
<a href="<%= new_user_path %>">注册</a>
</div>
</div>
</div>
<div class="form-group">
<div class="col-lg-12">
<input type="submit" name="sign_submit" value="登陆" class="col-xs-12 btn btn-primary">
</div>
</div>
<% end %>
参考资料
- gem sorcery的使用
- 参考博客原话:我的github上一个项目用的这个gem,懒得研究的同学直接去我我的github上面copy代码吧…
- Sorcery具体使用