rails7: 前台用户 users/登录/注册 - 非 API 版本
利用rails的 has_secure_password 来开发登录,注册功能
需求
- 前台用户表:
users
- 用户登录功能,配合
sessions
资源的操作概念 - rails
session
的使用(注意: 与上面的sessions
一点关系没有)
在Gemfile中添加 bcrypt
gem 'bcrypt', '~> 3.1.7'
生成 users
rails generate resource User username:string password_digest:string
rails
rails db:migrate
最关键的路由
查看自定义路由:
rails routes | grep -v /rails/
# 理论上
rails generate controller Users new create
rails generate controller Sessions new create destroy
# 实际上,我们用一步实现即可
rails g resource User username:string password_digest:string
# 带上 conroller 一起创建
rails g resource User username:string password_digest:string
rails g controller Users new create
# 需要删除 create 这个产生的 view
rails generate controller Sessions new create destroy
功能 | 路由 |
---|---|
注册 - users |
|
注册页面 |
|
注册 post |
|
登录相关 - sessions |
|
登录页面 |
|
登录 post |
|
登出 logout |
|
路由最终定义
Rails.application.routes.draw do
root "pages#welcome"
resources :users, only: [:show, :create]
resources :sessions, only: [:create]
get 'signup' => 'users#new'
get 'login' => 'sessions#new'
delete 'logout' => 'sessions#destroy'
get "up" => "rails/health#show", as: :rails_health_check
end
登录表单
文件位置
app/views/sessions/new.html.erb
<h1>Sessions#new</h1>
<h2>Login</h2>
<%= form_with(model: @user, url: sessions_path) do |form| %>
<p>
<%= form.label :username %>
<%= form.text_field :username %>
</p>
<p>
<%= form.label :password %>
<%= form.password_field :password %>
</p>
<p>
<%= form.submit "Login" %>
</p>
<% end %>
注册表单
文件位置
app/views/users/new.html.erb
<h1>Users#new</h1>
<%= form_with(model: @user, url: users_path) do |form| %>
<p>
<%= form.label :username %>
<%= form.text_field :username %>
</p>
<p>
<%= form.label :password %>
<%= form.password_field :password %>
</p>
<p>
<%= form.label :password_confirmation %>
<%= form.password_field :password_confirmation %>
</p>
<footer>
<%= form.submit "Register" %>
</footer>
<% end %>
sessions
文件
app/controllers/sessions_controller.rb
# app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by(username: params[:session][:username])
if user && user.authenticate(params[:session][:password])
# 登录成功
session[:user_id] = user.id
redirect_to root_path, notice: '登录成功!'
else
# 登录失败
flash.now[:alert] = '用户名或密码错误'
render :new
end
end
def destroy
# 注销
session[:user_id] = nil
redirect_to root_path, notice: '已注销'
end
end
users_controller
# app/controllers/users_controller.rb
class UsersController < ApplicationController
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
session[:user_id] = @user.id
redirect_to root_path, notice: '注册成功!'
else
render :new
end
end
private
def user_params
params.require(:user).permit(:username, :password, :password_confirmation)
end
end
要不要用 profile
推荐不要改成
profile
的形式
# 用 profile
get 'profile/:id' => 'users#show', as: :profile
# 路由 profile/3
# path: profile_path(user)
# 不用的情况
resources :users, only: [:show, :create]
# 路由 users/3
# path: user_path(user)