PHP登录/身份验证/会话/ API /令牌

时间:2016-11-08 10:14:06

标签: php login token

我需要开发一个非常安全的登录系统。

我有一个API层,我的计划是创建一个令牌表。我将用户名/密码(Post)发送到我的API,然后生成一个唯一的令牌(一次性令牌,时间有限),我以JSON格式返回令牌。

我的问题是:

  1. 用户登录时应该保存在会话中的内容。我希望尽可能少地存储信息。我应该只保存令牌吗?安全吗?

  2. 我不想在会话中存储访问级别和用户信息,然后我需要每次通过令牌获取这些信息..你怎么看?咨询!

  3. 开发更安全的登录系统的任何其他建议。

  4. 提前谢谢你。

2 个答案:

答案 0 :(得分:1)

由于您希望将会话保持为已登录的身份证明,因此您可能会遇到一个问题:某些客户端无法保持会话状态。

例如,手机,基于网络的应用程序。

我正在创建一个类似的项目。我的解决方案是

  1. 创建一个名为session(或任何你想要的)的表格,保留UserToken(随机生成),UserIDTokenExpire
  2. 用户登录后,在session表创建一条记录,并将令牌返回给用户(编码为JSON)。
  3. 用户保留自己的token,并在每个请求上附加token。 (无论是正文还是标题,我都使用标题来分隔数据)。
  4. 每次在询问之前检查token。例如,token是否存在? token已过期吗?用户是否被阻止?
  5. 通过步骤4.,您还可以通过相对查询获得用户的内容。
  6. 这是我的解决方案。它与你的方式相似。

    此外,为了提高安全性,请按照以下方式进行操作

    1. 使用SSL(HTTP)保护服务器和客户端之间的连接。
    2. 不要保留Password明文。你应该加密它们。
    3. 您可以尽可能长时间生成token
    4. token表的session字段应区分大小写。更改与_ci不同的排序规则(表示不区分大小写
    5. 检查POST数据以阻止SQL Injection永远不要相信用户提供的内容。
    6. 以上说明是基本的。我总是这样做。

答案 1 :(得分:1)

这只是一个关于如何使用会话,cookie以及数据库和php处理它的小清单:P 不是JSON

您可以使用这样的数据库 db_for_log_reg

因此会话应包含一个带有登录索引的数组,以便稍后检查会话是否设置并限制对 user_only_page 的访问。像这样:

$_SESSION = array(
  "login" => true,
  "data" => array(
      "username" => $row["username"], // is not a must and not unsafe / you can let it out if you want
      "email" => $row["email"], // this is also not a must
      "time" => time()+60*10 // so here you can set a time how long the session is available. for this example it is 10min.
  )
);

为" remember_me"设置一个Cookie像这样的复选框:

if (isset($_POST["remember_me"]) && $_POST["remember_me"] === "accepted") {
     $_SESSION = array(
           "login" => true,
           "data" => array(
              "username" => $row["username"], //not a must
              "email" => $row["email"], //also not a must
              "time" => time() +3600*24*30 //set the time higher, so that the user won't bee kicked out after 10min when he logged in.
             )
       );
    setcookie('remember_me', md5($emailUsername . time()), time() +3600*24*30);
}

然后您可以编写一个文件,该文件包含在每个页面中并处理所有会话或cookie。像这样:

ob_start(); //Turns on the output buffering

if (isset($_SESSION["login"])) { //here we check if the session isset(true)

    if ($_SESSION["data"]["time"] >= time()) { //here we check if the session time we set before to 10min is greater than the actual time
        if(isset($_COOKIE["remember_me"])) { //if you want to let the user stayed in check if the cookie isset, and if redirect him directly to the userarea
            header('Location: ../path_to_theuserarea/userarea.php'); //the redirect
            exit();
        }
    }
    else { // here we go if the session time is lower than the actual time and kick the user out
        $_SESSION["login"] = false; //he has to  log_in again
        header('Location: ../path_to_the_login/login.php'); //redirect to the login.php
        exit();
    }
}
else { //here we check if the requested basename of a file is not login.php and if, redirect him to login.php. thats the part that will be included in your userarea.php
    if (basename($_SERVER["REQUEST_URI"]) !== "login.php") {
        header('Location: ../path_to_the_login/login.php'); //redirect back to login
    }
}
ob_end_flush(); //end buffering


对安全登录/注册系统也有好处:

  1. Account_Activation_Token:在成功注册到用户输入的电子邮件后发送令牌,只有在他点击该链接时才允许他登录。我自己使用了这种方法,并使用$_GET作为激​​活令牌。发送https://YOUR_URL/log_reg/activateAccountWithToken.php?id=USERID&activation_token=RANDOMLY-STRING-WITH-50-CHARAKTERS
  2. 等链接
  3. 您也可以.htaccess重写网址,以便更好地显示网址。像这样:
  4. <IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteBase /log_reg/
        RewriteRule ^activate/([a-z]+)/?$   activationToken.php?id=$1   [NC,L]
    </IfModule>
    

    之后您可以使用https://YOUR_URL/log_reg/activate/USERID/

    之类的网址
    1. 您可以使用Cronjob在一段时间后从数据库中删除所有激活令牌,以便用户必须再次激活其帐户。
    2. 永远不要存储PLAINTEXT_PASSWORDS,使用password_hash()和password_verify()等函数
    3. 在用户登录时使用password_needs_rehash()函数,以便每次登录时都会重新生成db中的哈希值。
    4. 使用.htaccess强制使用SSL并使用 prepared-statements 将数据插入数据库