在PHP登录脚本中使用会话和会话变量

51

我刚刚用PHP创建了一个完整的登录和注册系统,但我的问题是我还没有使用任何会话技术。我在PHP方面有点新手,以前从未使用过会话技术。我想做的是,用户注册并填写登录表单后,他们仍然停留在同一页上。因此,页面的一部分将是如果会话已登录,另一部分则是否则(用户未登录,因此显示登录表单)。有人可以告诉我如何入手吗?


2
如果你能够想象一本完整回答你问题的书,那么你的要求就过高了。为了澄清,你的问题范围太广泛了。 - orourkek
这并不是什么前所未有的事情。看看php.net的会话文档,那是一个很好的起点:] - orourkek
请看这个链接:http://www.phpro.org/tutorials/Introduction-To-PHP-Sessions.html - The Alpha
2
也可以尝试这个 http://www.9lessons.info/2009/09/php-login-page-example.html - The Alpha
9个回答

97
开始会话,需要在页面顶部或在调用会话代码之前执行此操作。
 session_start(); 
将用户ID放入会话中以跟踪登录用户。
 $_SESSION['user'] = $user_id;

检查是否有用户已登录

 if (isset($_SESSION['user'])) {
   // logged in
 } else {
   // not logged in
 }

查找已登录用户的ID

$_SESSION['user']

所以在你的页面上

 <?php
 session_start();


 if (isset($_SESSION['user'])) {
 ?>
   logged in HTML and code here
 <?php

 } else {
   ?>
   Not logged in HTML and code here
   <?php
 }

29

以下是使用PHP编写的最简单的会话代码,共使用3个文件。

login.php

<?php  session_start();   // session starts with the help of this function 


if(isset($_SESSION['use']))   // Checking whether the session is already there or not if 
                              // true then header redirect it to the home page directly 
 {
    header("Location:home.php"); 
 }

if(isset($_POST['login']))   // it checks whether the user clicked login button or not 
{
     $user = $_POST['user'];
     $pass = $_POST['pass'];

      if($user == "Ank" && $pass == "1234")  // username is  set to "Ank"  and Password   
         {                                   // is 1234 by default     

          $_SESSION['use']=$user;


         echo '<script type="text/javascript"> window.open("home.php","_self");</script>';            //  On Successful Login redirects to home.php

        }

        else
        {
            echo "invalid UserName or Password";        
        }
}
 ?>
<html>
<head>

<title> Login Page   </title>

</head>

<body>

<form action="" method="post">

    <table width="200" border="0">
  <tr>
    <td>  UserName</td>
    <td> <input type="text" name="user" > </td>
  </tr>
  <tr>
    <td> PassWord  </td>
    <td><input type="password" name="pass"></td>
  </tr>
  <tr>
    <td> <input type="submit" name="login" value="LOGIN"></td>
    <td></td>
  </tr>
</table>
</form>

</body>
</html>

home.php

<?php   session_start();  ?>

<html>
  <head>
       <title> Home </title>
  </head>
  <body>
<?php
      if(!isset($_SESSION['use'])) // If session is not set then redirect to Login Page
       {
           header("Location:Login.php");  
       }

          echo $_SESSION['use'];

          echo "Login Success";

          echo "<a href='logout.php'> Logout</a> "; 
?>
</body>
</html>

退出.php

<?php
 session_start();

  echo "Logout Successfully ";
  session_destroy();   // function that Destroys Session 
  header("Location: Login.php");
?>

8
首先,PHP文档提供了一些关于会话的优秀信息
其次,您需要一种方式来存储网站每个用户的凭据(例如数据库)。最好不要将密码存储为可读的未加密纯文本。在存储密码时,应使用PHP的crypt()哈希函数。这意味着如果凭据被泄露,密码不会轻易被获取。
大多数登录系统将哈希/加密用户输入的密码,然后将结果与存储系统(例如数据库)中相应用户名的哈希进行比较。如果输入的密码哈希值与存储的哈希值匹配,则用户已输入正确的密码。
您可以使用会话变量来存储有关用户当前状态的信息-即他们是否已登录,如果已登录,则还可以存储其唯一用户ID或任何其他需要轻松获取的信息。
要开始一个PHP会话,您需要调用session_start()。同样地,要销毁会话及其数据,您需要调用session_destroy()(例如,当用户注销时)。
// Begin the session
session_start();

// Use session variables
$_SESSION['userid'] = $userid;

// E.g. find if the user is logged in
if($_SESSION['userid']) {
    // Logged in
}
else {
    // Not logged in
}

// Destroy the session
if($log_out)
    session_destroy();

我建议你也可以看一下this。那里有一些易于理解的好资料,关于创建一个简单的登录系统。

PHP 5.5 引入了密码哈希函数(提供了 5.3.7 兼容代码),应用于生成和验证密码哈希。这些函数消除了某些程序员在使用crypt()或其他 PHP 通用哈希函数时可能会犯的削弱安全性的错误。有关为什么要使用 password_hash() 而不是 crypt() 的详细信息,请参见 rfc:password_hash - Jody Bruchon
你回答底部的链接(this)现在已经失效了。你能提供这个资源的永久链接吗? - dmcgill50

6

我一直使用面向对象编程,并使用这个类来维护会话,所以你可以使用函数is_logged_in检查用户是否已登录,如果没有,则可以执行你想要的操作。

<?php
class Session
{
private $logged_in=false;
public $user_id;

function __construct() {
    session_start();
    $this->check_login();
if($this->logged_in) {
  // actions to take right away if user is logged in
} else {
  // actions to take right away if user is not logged in
}
}

public function is_logged_in() {
   return $this->logged_in;
}

public function login($user) {
// database should find user based on username/password
if($user){
  $this->user_id = $_SESSION['user_id'] = $user->id;
  $this->logged_in = true;
  }
}

public function logout() {
unset($_SESSION['user_id']);
unset($this->user_id);
$this->logged_in = false;
}

private function check_login() {
if(isset($_SESSION['user_id'])) {
  $this->user_id = $_SESSION['user_id'];
  $this->logged_in = true;
} else {
  unset($this->user_id);
  $this->logged_in = false;
 }
}

}

$session = new Session();
?>

1
谢谢,这是一个很好的开始,但应该扩展您的类以使用电子邮件进行用户身份验证;) - The Bumpaster

0
这是一个单页登录/登出系统示例。
密码永远不会被暴露,HASH + SALT 和任何人查看带有散列盐密码的数据库表一样安全

首先,使用此sandbox.io创建一个加盐密码$hash,并确保用下面的$hash的***替换结果字符串。

index.php单页:

<?php
// stackoverflow.com/a/67661402/383904
session_start();

$username = "pony";
$salt = "PonieshaveunicornS"; // Use something really custom instead of ponies
$hash = "***"; // Replace *** with the result of: echo hash("sha256", "myPassword".$salt);

$url = strtok($_SERVER["PHP_SELF"], '?');
$errorMessage = ""; // Used for login error messages


// LOGOUT SYSTEM
if (isset($_GET["p"]) && $_GET["p"] == "logout"):
    session_destroy();
    header("Location: $url");
    exit;
endif;


// LOGIN SYSTEM
if (isset($_POST['un']) && isset($_POST['pw'])):

  sleep(3); // Makes it ages slower for rainbow attacks

  if ($_POST['un'] == $username && hash("sha256", $_POST['pw'].$salt) == $hash):
    $_SESSION['_reg'] = $_POST['un'];
    header("Location: $url");
    exit;
  else:
    $message = "Incorrect login data";
  endif;
endif;


// DETERMINE A VALID LOGIN
$isLoggedIn = isset($_SESSION['_reg']) && $_SESSION['_reg'] == $username;


// YOUR CUSTOM LOGGED-IN METHODS AND STUFF
if ($isLoggedIn):

  // I.e: your DB connections, functions, methods, etc...

endif;
?>

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My app</title>
</head>
<body>

  <div id="app">
    <?php if ($isLoggedIn): ?>
            
      <h1>Welcome <?= $_SESSION["_reg"] ?></h1>
      <a href="?p=logout">Logout</a>

    <?php else: ?>

      <h1>LogIn</h1>

        <form action="./index.php" method="post">
          <label><input type="text" name="un" placeholder="Username" /></label><br>
          <label><input type="password" name="pw" placeholder="Password"/></label><br>
          <input type="submit" id="submit" value="LOGIN" />
        </form>

        <b><?= $errorMessage ?></b>

    <?php endif; ?>
  </div>

</body>
</html>

免责声明:请注意上述内容

  • 虽然不算太糟糕,但是
  • 应该使用SHA轮和/或比SHA256更强的算法进行改进
  • 永远不要将秘密(盐)或哈希硬编码到可分发的文件中
  • 仍然容易受到会话劫持的攻击
  • 它可以被格式错误/损坏的服务器文件类型响应所暴露(Facebook'07综合症)
  • 将这样的代码与公开的git repo一起推送是不专业的(即:禁止),因为其中包含了暴露的秘密盐和哈希
  • 对于一个短期的“登录查看某些内容”项目来说,可能还可以接受
  • 您绝不能“只是复制粘贴”来自Stack Overflow的代码/脚本,而没有适当、深入的理解。

0
//start use session

$session_start();

extract($_POST);         
//extract data from submit post 

if(isset($submit))  
{

if($user=="user" && $pass=="pass")

{

$_SESSION['user']= $user;   

//if correct password and name store in session 

}
else {

echo "Invalid user and password";

header("Locatin:form.php");

}

if(isset($_SESSION['user'])) 

{

//your home page code here

exit;
}

顺便提一下,你应该对此进行哈希和加盐处理。然后对输入进行哈希和加盐以进行比较。 - AbsoluteƵERØ

-2
$session_start();

extract($_POST);         
//extract data from submit post 

if(isset($submit))  
  {    
    if($user=="user" && $pass=="pass")    
      {     
        $_SESSION['user']= $user;       
        //if correct password and name store in session 
    } else {
        echo "Invalid user and password";
        header("Locatin:form.php")
    }
if(isset($_SESSION['user']))     
  {
  }

-3

你需要在页面顶部开始会话或在调用会话代码之前开始会话

session_start(); 

-3
$session_start();

extract($_POST);         
//extract data from submit post 

if(isset($submit))  
{

if($user=="user" && $pass=="pass")

{

$_SESSION['user']= $user;   

//if correct password and name store in session 

}
else {

echo "Invalid user and password";

header("Locatin:form.php");

}

if(isset($_SESSION['user'])) 

{

//your home page code here

exit;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接