2

我对登录系统比较陌生。CodeIgniter 可以将会话存储在数据库中,这就是我正在做的事情。它存储基础知识:session_id、ip、代理和 last_activity,并可选择存储自定义数据。我已经阅读了一些教程,据我所知,这是它应该如何工作的:

  1. 检查用户是否存在会话(这是必要的吗?)

  2. 如果用户名不存在,请检查会话数据库中的用户名(这将是会话数据库中的自定义条目),然后显示登录表单。(登录后将用户名保存到会话数据库)

  3. 如果会话数据库中存在用户名,请检查 last_activity。如果它比期望的旧(或者会话已过期),则显示登录表单。如果它不是太旧,请登录。

  4. 要注销,您只需从会话数据库中删除用户名。(或者我应该使用$this->session->sess_destroy():)

那有意义吗?我是否还应该将用户的加密密码存储在会话数据库中并进行检查?有更好/不同的方法吗?

谢谢。

4

4 回答 4

7

我认为你的方法正在走向一个稍微错误的方向,但它根本没有错。你应该把它分开一点。

会话的实际作用是存储多个请求所需的数据。

CodeIgniter 中的会话表与用户信息无关。它只负责存储会话相关数据(session_id 等)。设置好表格后,您可以按照习惯使用 CodeIgniter 会话。它将为您处理会话管理过程。

那么让我们来看看登录的过程。

首先,您需要一个存储用户信息的表。该表的最简约的实现是:

users(user_id, username, password)

我在会话中存储的唯一信息是用户 ID。因此,每当用户进入您的页面时,您应该检查是否有带有您的用户 ID 的会话字段。

if($this->session->userdata('user_id'))
{
  //User is logged in
}
else
{
  //User is not logged in
}

如果用户未登录,您需要显示您的登录表单。用户发送表单后,您需要验证输入并检查登录尝试是否成功。您的模型方法可能如下所示

public function attemptLogin($username, $password)
{
  $query = $this->db->get_where('users', array(
    'username' => $username,
    'password' => $this->mysecurityclass->superDuperHashMethod($password)
  ));
  if($query->num_rows() == 0)
    return false;
  return $query->row()->user_id;
}

我们在这里所做的是检查是否存在与用户输入匹配的数据集。正如你所问的,我提供了一个简单的例子,如何进行散列。当然,您需要自己实现散列功能或使用任何现成的类。由你决定。也许您甚至应该更多地封装它并且已经将散列密码传递给该方法。

如果输入的凭据与用户表中的数据集匹配,该方法将返回用户 ID。我们知道此时用户已成功登录。获得用户 ID 后,将其存储在会话中。

$userid = $this->user_model->attemptLogin($username, $pass);
if(!$userid)
{
  //GTFO, login was not successfull
}
else
{
  $this->session->set_userdata('user_id', $userid);
  redirect('home');
}

因此,当登录成功时,您设置会话密钥并重定向用户。现在这个过程又开始了。但是现在我们有一个会话集,我们的初始检查是否有会话字段集将通过。我们的用户已登录。

要注销用户,您只需像您已经提到的那样简单地销毁会话。由于会话密钥 user_id 将不再设置,因此我们的初始检查将返回 false,并且将再次提示用户进入登录表单。

正如你看到的。您不必关心会话是如何在内部处理的。随意询问是否有不清楚的地方。

注意:代码示例仅用于说明目的。您需要自己考虑实施:)

快乐编码!

于 2013-08-02T08:11:15.907 回答
2

请看我的评论:

1.检查用户是否存在会话(有必要吗?)

评论:是的,这是必要的,因为它告诉特定用户是否已登录,并且可以基于此进行一些活动。喜欢如果登录则重定向到主页或登录/注册页面如果没有

2.检查会话数据库中的用户名(这将是会话数据库中的自定义条目),如果它不存在,则显示登录表单。(登录后将用户名保存到会话数据库)

评论:见上面的评论。

3.如果会话数据库中存在用户名,请检查last_activity。如果它比期望的旧(或者会话已过期),则显示登录表单。如果它不是太旧,请登录。

评论:您可以根据您的要求修改此功能。

4.要注销,您只需从会话数据库中删除用户名。(或者我应该使用:$this->session->sess_destroy())。

评论:您需要将其从 db.xml 中删除。

默认情况下,CodeIgniter 将会话数据存储在 cookie 中,大小上限为 2KB-4KB,具体取决于浏览器。如果您尝试在会话中存储超过 4KB 的数据,您将开始遇到问题。

您可以在这里获得更多信息:详细博客:http: //goo.gl/YPllj0

于 2013-08-02T08:04:06.040 回答
1

是否要存储取决于您和您的user information要求database

  1. 有必要,当用户突然登录或假设他关闭浏览器时,默认情况下他应该登录。
  2. 是的,当您没有session-id用户时,您可以向他展示login-form注销后也session-id entry应该删除。
  3. 您可以删除所有旧条目,并显示login-form.
  4. 注销后,您应该清除会话删除数据库条目。codeigniter已将session 存储在 cookie Read session中的一件事,因此请检查是否cookies也已清除。为此,您可以从此处使用Codeigniter 本机会话库
于 2013-08-02T08:08:24.843 回答
0

会话数组的一个有用方面是您可以将自己的数据添加到其中,并将其存储在用户的 cookie 中。你为什么想做这个?这是一个例子:

假设某个特定用户登录到您的网站。一旦通过身份验证,您就可以将他们的用户名和电子邮件地址添加到会话 cookie 中,从而使您可以在全球范围内使用该数据,而无需在需要时运行数据库查询。

要将数据添加到会话数组中,需要将包含新数据的数组传递给此函数:

$this->session->set_userdata($array);

其中 $array 是一个包含新数据的关联数组。这是一个例子:

$newdata = array(
    'username'  => 'johndoe',
               'email'     => 'johndoe@some-site.com',
               'logged_in' => TRUE
           );

$this->session->set_userdata($newdata);

如果你想一次添加一个值, set_userdata() 也支持这种语法。

$this->session->set_userdata('some_name', 'some_value');
于 2014-12-08T13:17:55.387 回答