1.什么叫用户登录注册系统呢?

假如你做一个放博客的网站,或个人网站,再或者写一些展示用的网站,例如一些小企业的官网,这类网站并不需要用户去注册,或者用户登录。而我所说的用户登录注册系统,按照名称也就分开两部分,第一用户能注册,第二用户能登录。如果博客需要别人来评论,或者你写一个电子商务的网站,有各种各样的客户信息,这个时候就是需要存储用户的个人资料等信息。或许你就需要开放用户登录注册功能了。只要想一下,就可以知道,这种需求是很常见的。所以网站具备一个用户登录注册系统的功能,作为开发人员是必须掌握的,这是基本中的基本。

我们先来分析一下。首先,注册是很简单的,不外乎,你的网站中的数据库有一张用户(users)表,用户表大约有名称,电子邮件,密码等内容,一般注册信息会填写的内容也可能就是这几项。注册一个用户也就是添加了一条记录罢了。这很简单。至于密码,肯定不是明文啦,这会用到加密手段,我们以后再说。

至于登录。我们来详细说说。首先想的是,登录也像注册那样,在数据表中创建一条记录。这显然不符合逻辑,注册一个用户创建一条记录是好的,一百个用户就有一百条记录,登录一次也创建一次,用户可能每天登录好几次,那就得创建好几条记录。这些记录存在数据库也没什么意思,其他的先不说,这点就不行。所以只能找其他方法。

2.会话

或许有人会跟你说,用session就好了。session是什么呢?我们来分析一下。

我们浏览网页用的是http协议,先不管这协议是什么,只要先当成生活中的一种协议就好了,也就是一种约定,大家遵守的约定。

而http是一种无状态的协议。无状态可以这么理解,就是不记录状态。我们浏览网页是发送一个http请求,假如点击一个按钮吧,就发送了一个请求,但我之后点击了另一个按钮,就发送了另一个请求,这两个请求没有记录状态,没有任何关系,最多就是从相同的ip,相同的地方发送出去。可以这样认同,它们彼此不认识。既然没有记录状态,那服务端自然不认识或区分两次点击是同一个人所为。就算是相同的ip可不见得是同一个人,共享ip可是很常见的。那怎么办呢。有一种方法是这样的,不是两个请求是不一样的吗,就这样,每次请求都带一个相同的能标明身份的标记,这样不就可以吗,那每次请求都要带,好麻烦,显然也不行。

3.实例

那就用session技术好了,session的中文名可以理解为会话。是服务器端提供的技术。可以先把它理解为存会话数据的地方。它是存在服务器端的。存的方式很多种,文件 ,内存,以cookie的形式存等。不管怎样,它就是服务器端来解决上面那个问题的。是来存放会话状态的。

来举个例子,用户总有自己的id,这个总能标明自己的身份,因为id是唯一的。session是存在于服务器间的,并且各个请求之间都会存在,也就是说是共享的。那我们用session[:user_id]来存用户的id。只要用户在登录时,把用户表中的id存入sessions[:user_id]既可。这样来简单说,登录时或许得输入用户名和密码,这个时候得找根据用户名去查数据库中的users表,再跟密码比对,如果比对成功,就会得到那个user的记录,这个记录也就是可以得到整个用户的信息的。比如:

  def login_as(user)
    session[:user_id] = user.id
    @current_user = user
  end

这个session[:user_id]就是服务器端和你主机保持的会话啦。这样并不是很清楚,我们从头来开始实现一个登录框,再加上登录的逻辑。

<% provide(:title, "Sign in") %>
<h1>Sign in</h1>

<div class="row">
  <div class="span6 offset3">
    <%= form_for(:session, url: sessions_path) do |f| %>

      <%= f.label :email %>
      <%= f.text_field :email %>

      <%= f.label :password %>
      <%= f.password_field :password %>

      <%= f.submit "Sign in", class: "btn btn-large btn-primary" %>
    <% end %>

    <p>New user? <%= link_to "Sign up now!", signup_path %></p>
  </div>
</div>

email就是邮箱啦,password自然就是密码,这很简单,就是让你输入邮箱还有密码,之后就能点登录啦。

登录之后的逻辑是这样的。

  def create
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      login_as user
      redirect_back_or user
    else
      flash.now[:error] = 'Invalid email/password combination'
      render 'new'
    end
  end

首先根据提交的邮箱,去数据库查找,如果找到的话,就跟密码匹配,是正确的密码才能让你登录啦。user.authenticate这个就是跟密码匹配的方法,登录成功之后呢,执行了这句login_as user,也就是上面的代码,就可以登录了。

我们还需要一个功能,有些功能,是不需要用户登录就能访问的,例如首页,有些功能是需要用户登录之后才能访问的,例如个人信息页面。还有,在导航条上,当用户没登录时,就显示登录的按钮,当登录时就显示个人信息的按钮。这种也是很常见的吧。那就这样来办吧。

  def user_signed_in?
    !!current_user
  end

  def current_user
    @current_user ||= login_from_session
  end

  def login_from_session
    if session[:user_id].present?
      begin
        User.find session[:user_id]
      rescue
        session[:user_id] = nil
      end
    end
  end

user_signed_in?是判断用户有没有登录的,没有登录的话就执行login_from_session通过session[:user_id],还有users表找出当前用户的记录,这样以前就可以在view上使用current_user.email等来显示邮箱了。

要退出也很简单,只要把current_user设为nil就好了,就是这样

  def logout
    session.delete(:user_id)
    @current_user = nil
    session.delete(:last_active_at)
    session.delete(:unique_session_id)
    forget_me
  end

以上就把登录系统简单说了一下,注册就不讲了,不就是创建一条记录罢了。


回复数量: 0
暂无评论~~