Rails学习者在这里尝试一些新的东西,通过构建一个有两个一半的应用程序,一半与另一半的学生合作。
已经建立了自己的公司有自己的控制器和模型,学生有自己的控制器和模型,其中两个用户类型通过相同的形式登录。(我知道我本可以以一种更基于角色的方式创建它,使用一个列来表示用户类型,但是从学习的角度来看,这种隔离对我来说更有意义)
我的问题是,当注册为新用户时,它会很好地登录,但是作为返回用户(学生或公司),它永远不会登录,即使在输入登录页面不断呈现的新凭据时也是如此。
据我所知,这是因为当搜索DB来认证用户而不是通过电子邮件进行搜索时,其搜索的电子邮件为空限制了1.
从“公司”选择“公司”.*,其中“公司”。“电子邮件”为空限制1。
任何帮助都是非常感谢的,学习rails当然是一段旅程!
希望我已经发布了足够的组件,如果我遗漏了什么,请告诉我。
会话主计长
class SessionsController < ApplicationController
def new
end
def create
if
@corporate = Corporate.authenticate(params[:email], params[:password])
session[:corporate_id] = @corporate.id
flash[:notice] = "Welcome back, #{corporate.firstname}!"
redirect_to (session[:intended_url] || @corporate)
session[:intended_url] = nil
elsif
@student = Student.authenticate(params[:email], params[:password])
if params[:remember_me]
cookies.permanent[:auth_token] = student.auth_token
else
cookies[:auth_token] = student.auth_token
end
flash[:notice] = "Welcome back, #{student.firstname}!"
redirect_to (session[:intended_url] || student)
session[:intended_url] = nil
else
flash.now[:warning] = "Kindly login with your email and password!"
redirect_to '/login'
#render :new
end
end
def destroy
if current_corporate
session.delete(:student_id) || cookies.delete(:auth_token)
else current_corporate
session[:corporate_id] = nil
end
redirect_to root_url, notice: "You have signed out!"
end
def logged_in?
!current_corporate.nil?
end
end公司财务总监
class CorporatesController < ApplicationController
def index
@Corporates = corporate.paginate(page: params[:page], :per_page => 5).includes(:profile)
end
def show
if params[:id]
@corporate = Corporate.find(params[:id])
# .includes(:profile)
else
@corporate = current_corporate
end
@searches = Search.where(corporate_id: @corporate).includes(:state, city: [:profile])
end
def new
@corporate = Corporate.new
#@corporateprofile = Corporateprofile.new
end
def create
@corporate = Corporate.new(corporate_params)
#@corporateprofile = Corporateprofile.new(corporate_idparams)
if @corporate.save
session[:corporate_id] = @corporate.id
redirect_to @corporate
#redirect_to corporate_path(current_corporate)
else
render :new
end
end
private
def corporate_params
params.require(:corporate).permit(:firstname, :lastname, :email, :password)
end
end企业模型
class Corporate < ActiveRecord::Base
mount_uploader :corp_image, CorpImageUploader
mount_uploader :logo, LogoUploader
has_secure_password
#made by tom to create profile
after_create :build_profile
#made by tom to link tables
has_many :searches, dependent: :destroy
has_one :corporate_profile,autosave: true, dependent: :destroy
validates :password, length: { minimum: 8, allow_blank: true }
validates :firstname, presence: true
validates :lastname, presence: true
validates :email, presence: true,
format: /\A\S+@\S+\z/,
uniqueness: { case_sensitive: false }
COMPANY_SIZE = ["1 - 10 Employees", "11 - 50 Employees", "51 - 100 Employees", "101 - 200 Employees", "201 - 500 Employees", "501 - 1000 Employees", "1001 - 5000 Employees", "5001 - 10000 Employees", "10001 - 20000 Employees", "20001 - 50000 Employees", "50001 - 100000 Employees", "100001 - 200000 Employees", "200000+ Employees"]
INDUSTRY = ['Accounting', 'Airlines/Aviation', "Alternative Disputs Resolution", "Alternative Medicine", "Animation", "Apparel & Fashion",
"Architecture & Planning", "Arts & Crafts", "Automotive", "Banking", "Biotechnology", "Broadcast Media", "Building Materials", "Capital Markets", "Commercial Real Estate",
"Computer Software", "Computer hardware & Network Security", "Construction", 'Consumer Electronics', 'Consumer Services', "Dairy", "Education Management", "E-Learning", "Entertainment", "Information Technology and Services",
"Hospital & Health Care", "Import and Export", "Internet", "Government", "Legal", "Management Consulting", "Marketing and Advertising", "Military", "Nonprofit Organization Management",
"Oil & Energy","Professional Training & Coaching", "Restaurants", "Research", "Security and Investigations", "Sports", "Staffing and Recruiting", "Transportation", "Venture Capital & Private Equity", "Other"]
#validates :sex, inclusion: { in: SEX }
before_create {generate_token(:auth_token)}
def send_password_reset
generate_token(:password_reset_token)
self.password_reset_sent_at = Time.zone.now
save!
CorporateMailer.password_reset(self).deliver
end
def generate_token(column)
begin
self[column] = SecureRandom.urlsafe_base64
end while Corporate.exists?(column => self[column])
end
def gravatar_id
Digest::MD5::hexdigest(email.downcase)
end
def self.authenticate(email_or_username, password)
corporate = Corporate.find_by(email: email_or_username)
corporate && corporate.authenticate(password)
end
def should_generate_new_friendly_id?
new_record?
end
#made by tom to build profile
def build_profile
CorporateProfile.create(corporate: self) # Associations must be defined correctly for this syntax, avoids using ID's directly.
end
end应用控制器
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
before_filter :expire_hsts
#helper_method :current_user
private
def require_signin_corporate
unless current_corporate
session[:intended_url] = request.url
redirect_to new_session_url, alert: "You need to login or register as corporate to post job"
end
end
helper_method :require_signin_corporate
def require_signin
unless (current_student || current_corporate)
session[:intended_url] = request.url
redirect_to new_session_url, alert: "You need to sign in to have access"
end
end
def require_signin_student
unless current_student
session[:intended_url] = request.url
redirect_to new_session_url, alert: "You need to sign in to have access"
end
end
helper_method :require_signin_student
def current_corporate
#@current_corporate ||= Corporate.find_by_auth_token!(cookies[:auth_token]) if cookies[:auth_token]
@current_corporate ||= Corporate.find(session[:corporate_id]) if session[:corporate_id]
end
helper_method :current_corporate
def current_student
@current_student ||= Student.find_by_auth_token!(cookies[:auth_token]) if cookies[:auth_token]
#@current_student ||= Student.find(session[:student_id]) if session[:student_id]
end
helper_method :current_student
def current_student?(student)
current_student == student
end
helper_method :current_corporate?
def current_corporate?(corporate)
current_corporate == corporate
end
helper_method :current_student?
def correct_student
@student = Student.friendly.find(params[:id])
unless current_student?(@student)
redirect_to root_url
end
end
def correct_student?
#current_student == correct_student
@correct_student == @student
end
helper_method :correct_student?
def correct_corporate
@corporate = Corporate.friendly.find(params[:id])
unless current_corporate?(@corporate)
redirect_to root_url
end
end
def correct_corporate?
#current_corporate == correct_corporate
@correct_corporate == @corporate
end
helper_method :correct_corporate?
def require_admin
unless current_student_admin? || current_corporate_admin?
redirect_to root_url, alert: "Unauthorized access!"
end
end
def current_corporate_admin?
current_corporate && current_corporate.admin?
end
def current_student_admin?
current_student && current_student.admin?
end
helper_method :current_corporate_admin?, :current_student_admin?
def require_author
unless current_corporate_author?
redirect_to root_url, alert: "Unauthorized access!"
end
end
def current_corporate_author?
current_corporate && current_corporate.author?
end
helper_method :current_corporate_author?
def require_pro
unless current_corporate_pro?
redirect_to root_url, alert: "Unauthorized access!"
end
end
def current_corporate_pro?
current_corporate && current_corporate.pro?
end
helper_method :current_corporate_pro?
def expire_hsts
response.headers["Strict-Transport-Security"] = 'max-age=0'
end
end登录表单(会话表单)
<%= bootstrap_form_for(:session, url: session_path) do |f| %>
<div class="field">
<%= f.email_field :email, :placeholder => "Email" %>
</div>
<div class="field">
<%= f.password_field :password, :placeholder => "Password" %>
<%= f.submit "Log in", class: "btn btn-primary block full-width m-b" %>
</div>
<a href="#">
<small>Forgot password?</small>
</a>
<p class="text-muted text-center">
<small>Do not have an account?</small>
</p>
<a class="btn btn-sm btn-white btn-block" href="/signup">Create an account</a>
<% end %>发布于 2016-02-16 13:41:32
使用两个不同的类进行身份验证会使事情变得更加复杂,而且进行授权也是相当困难的。
同样正确的是,使用基于角色的系统通常更可取。它有助于保持授权和身份验证的分离,并将极大地简化处理用户的逻辑,并大大减少重复的数量。
重构
但是让我们看看如何开始修复当前的设置。
您可能要做的第一件事是流行,以便您的应用程序对两个类使用相同的逻辑。并确保您只具有在应用程序中的一个位置上如何将用户序列化/从会话中清除的逻辑。
# app/helpers/sessions_helper.rb
module SessionsHelper
def current_user
if session[:corporate_id]
resource_class = Corporate
id = session[:corporate_id]
elsif session[:student_id]
resource_class = Student
id = session[:student_id]
end
@current_user ||= resource_class.find(id)
end
def signed_in?
current_user.present?
end
def sign_in!(resource)
reset_session # this helps combat session fixation attacks
session[@resource.model_name.i18n_key] = resource.id
@current_user = resource
end
def sign_out!
reset_session
end
end关键之一是我们在登录和退出用户时都使用reset_session。它使当前会话标识符无效,并生成一个新的会话标识符,是抵御会话固定/劫持攻击的重要防御措施。
我们还设置了一个current_user,它并不真正关心是Corporate还是Student。要检查,只需执行以下操作:
current_user.is_a?(Corporate)让我们在控制器中包括这个助手:
class ApplicationController < ActionController::Base
include SessionsHelper
# ...
end让我们以同样的方式重构SessionsController:
class SessionsController
# ...
def create
@resource = Corporate.authenticate(params[:email], params[:password])
@resource ||= Student.authenticate(params[:email], params[:password])
if @resource
# we need to store this since we are resetting the session.
intended_url = session[:intended_url]
sign_in!(@resource)
flash[:success] = "Welcome back, #{ @resource.firstname }!"
redirect_to(intended_url || root_path)
else
# don't use flash.now when redirecting!
flash[:warning] = "Kindly login with your email and password!"
redirect_to '/login'
end
end
def destroy
if signed_in?
sign_out!
redirect_to root_path, notice: 'You have been signed out!'
else
redirect_to root_path, error: "You are not signed in!"
end
end
end您还希望更改您的公司/ StudentsController创建方法,以便它使用相同的登录逻辑:
class CorporatesController
#...
def create
@corporate = Corporate.new(corporate_params)
#@corporateprofile = Corporateprofile.new(corporate_idparams)
if @corporate.save
sign_in! @corporate
redirect_to @corporate
else
render :new
end
end
endhttps://stackoverflow.com/questions/35425885
复制相似问题