深入理解Cookies、Sessions与访问控制
在网站开发中,用户登录是一个常见且重要的功能。用户输入用户名和密码,从而访问其账户独有的内容。然而,由于HTTP协议本身是无状态的,实现登录系统对于开发者来说并非易事。为了解决这个问题,我们可以使用Cookies和Sessions这两种技术来存储和管理用户信息。
1. Cookies是什么
如今,大多数计算机程序都会保存某种状态信息,比如应用程序窗口的位置或最近处理的文件名称等。这些信息通常存储在系统的小文件中,下次程序运行时可以读取。当网页设计从静态页面发展到完整的交互式在线应用时,网页浏览器也需要类似的功能,于是Cookies应运而生。
Cookies是与特定网站关联的名 - 值对,存储在客户端(浏览器)的计算机上。一旦网站设置了Cookies,后续对该网站的所有页面请求都会将Cookies中存储的信息发送回网站,直到Cookies过期或失效。而且,其他网站无法访问你网站设置的Cookies,反之亦然。因此,Cookies是相对安全的存储个人信息的地方,本身不会侵犯用户隐私。
2. PHP生成Cookies的生命周期
PHP生成的Cookies的生命周期如下:
1. 浏览器请求一个对应PHP脚本的URL,该脚本中调用了PHP内置的
setcookie
函数。
2. PHP脚本生成的页面连同包含Cookies名称(如
mycookie
)和值的HTTP
set-cookie
头一起发送回浏览器。
3. 浏览器收到这个HTTP头后,创建并存储指定的值为名为
mycookie
的Cookies。
4. 后续对该网站的页面请求包含一个HTTP
cookie
头,将名 - 值对(
mycookie=value
)发送到请求的脚本。
5. 当PHP收到带有Cookies头的页面请求时,会自动在
$_COOKIE
数组中创建一个以Cookies名称(
$_COOKIE['mycookie']
)和值为内容的条目。
下面是
setcookie
函数的定义:
bool setcookie ( string $name [, string $value = "" [,
int $expire = 0 [, string $path = "" [,
string $domain = "" [, bool $secure = false [,
bool $httponly = false ]]]]]] )
方括号
[…]
表示函数的参数是可选的,你可以省略这些参数,PHP会自动设置一些默认值。
需要注意的是,
setcookie
函数会向页面添加HTTP头,因此必须在实际页面内容发送之前调用。如果在页面内容发送到浏览器后调用
setcookie
,会产生PHP错误消息。
3.
setcookie
函数参数详解
| 参数 | 说明 |
|---|---|
name
|
指定Cookies的名称,是唯一必需的参数。仅使用此参数调用
setcookie
会删除浏览器中存储的同名Cookies(如果存在)。
|
value
| 用于创建新的Cookies或修改现有Cookies的值。 |
expire
|
指定Cookies的过期时间,以1970年1月1日为起始的秒数。默认情况下,Cookies会在浏览器关闭时删除。可以使用
time()
函数获取当前时间,例如
setcookie('mycookie', 'somevalue', time() + 3600 * 24 * 365)
设置Cookies在1年后过期;
setcookie('mycookie', '', time() - 3600 * 24 * 365)
删除已设置过期时间的Cookies。
|
path
|
限制对Cookies的访问范围到服务器上的指定路径。例如,设置路径为
/admin/
,只有对
admin
目录(及其子目录)的页面请求才会包含该Cookies。
|
domain
|
限制Cookies的访问范围到指定的域名。默认情况下,Cookies只返回给最初发送它的主机。对于大型公司的多个主机名,可以设置为
.example.com
,允许以
.example.com
结尾的任何主机访问Cookies,但Cookies不会在不同域名之间共享。
|
secure
|
设置为
1
时,表示Cookies只应通过安全(SSL)连接(即URL以
https://
开头)的页面请求发送。
|
httponly
|
设置为
1
时,告诉浏览器阻止网站上的JavaScript代码访问设置的Cookies,提高数据安全性。
|
虽然除
name
外的所有参数都是可选的,但如果要指定后续参数的值,必须先指定前面参数的值。
4. Cookies使用示例
假设我们想在用户首次访问网站时显示特殊的欢迎消息,可以使用Cookies记录用户的访问次数:
<?php
if (!isset($_COOKIE['visits'])) {
$_COOKIE['visits'] = 0;
}
$visits = $_COOKIE['visits'] + 1;
setcookie('visits', $visits, time() + 3600 * 24 * 365);
if ($visits > 1) {
echo "This is visit number $visits.";
} else {
// First visit
echo 'Welcome to our website! Click here for a tour!';
}
这段代码首先检查
$_COOKIE['visits']
是否已设置,如果未设置则将其初始化为0。然后计算当前访问次数并使用
setcookie
更新Cookies。最后根据访问次数显示相应的消息。
5. Cookies的局限性
在使用Cookies时,我们需要注意以下局限性:
-
数量和大小限制
:浏览器对每个网站允许的Cookies数量和大小有限制。一些浏览器在设置20个Cookies后会开始删除旧的Cookies以腾出空间,其他浏览器最多允许50个Cookies。此外,浏览器还对所有网站的Cookies总大小有上限,过多的Cookies可能导致自己网站的Cookies被删除。
-
性能影响
:每次访问网站时,所有Cookies都会被发送到服务器。如果Cookies中存储了大量信息,会增加数据传输量,降低网站的响应速度。
-
安全性问题
:Cookies的安全性取决于使用的计算机。任何能够访问存储Cookies的计算机的人都可以读取Cookies中的信息。
因此,我们应尽量减少网站创建的Cookies数量和大小。
6. PHP Sessions
由于Cookies存在上述局限性,不适合存储大量信息。例如,在电子商务网站中使用Cookies存储购物车商品信息时,可能会遇到浏览器Cookies限制的问题。为了解决这个问题,PHP引入了Sessions技术。
Sessions允许我们将数据存储在Web服务器上,而不是客户端浏览器中。浏览器中只存储一个包含用户会话ID的Cookies,这是一个由字母和数字组成的长字符串,用于在用户访问网站期间唯一标识该用户。PHP会根据这个会话ID加载与之关联的存储数据。
在使用PHP的会话管理功能之前,需要确保
php.ini
文件的相关部分已正确设置。以下是一些关键的设置项:
session.save_handler = files
session.save_path = "/tmp"
session.use_cookies = 1
-
session.save_handler:指定会话数据的存储方式,这里设置为files表示使用文件存储。 -
session.save_path:指定PHP创建用于跟踪会话的临时文件的目录。该目录必须存在于系统中,并且PHP运行的用户具有写入权限。在macOS和Linux系统中,/tmp是常用的选择;在Windows系统中,可以使用C:\WINDOWS\TEMP或其他目录。 -
session.use_cookies:设置为1表示使用Cookies来存储会话ID。
设置完成后,需要重启Web服务器软件使更改生效。
7. 常用的会话管理函数
-
session_start():告诉PHP查找会话ID,如果未找到则启动新会话。如果找到现有会话ID,PHP会恢复该会话的变量。由于该函数会尝试创建Cookies,因此必须在任何页面内容发送到浏览器之前调用。
session_start();
-
创建会话变量
:通过在特殊的
$_SESSION数组中设置值来创建会话变量。例如:
$_SESSION['password'] = 'mypassword';
需要注意的是,在调用
session_start()
之前,
$_SESSION
变量为空,因此在会话启动之前不要读写该变量。
-
删除会话变量
:使用PHP的
unset
函数可以从当前会话中删除变量。
unset($_SESSION['password']);
-
结束会话
:如果要结束当前会话并删除所有注册的变量,可以清空
$_SESSION数组并调用session_destroy函数。
$_SESSION = [];
session_destroy();
8. Sessions工作原理
当调用
session_start()
时,PHP会创建一个包含唯一ID的Cookies来代表每个用户。例如,第一个访问网页的用户可能是ID 1,第二个是ID 2,以此类推。用户访问下一个页面时,会将这个ID发送回网站,PHP根据该ID检索存储的用户信息。
在实际应用中,会话ID并不是简单的顺序数字,而是复杂、难以猜测的字符串。如果会话ID容易被猜测,黑客可以通过修改会话Cookies中的ID来冒充其他用户。
综上所述,Cookies和Sessions是网站开发中用于存储和管理用户信息的重要技术。Cookies适合存储少量信息,而Sessions则更适合处理大量数据。合理使用这两种技术可以提高网站的用户体验和安全性。
下面是Cookies和Sessions的使用流程对比图:
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
A([用户访问网站]):::startend --> B{使用Cookies?}:::process
B -->|是| C(设置Cookies):::process
C --> D(后续请求携带Cookies):::process
D --> E(服务器读取Cookies信息):::process
B -->|否| F{使用Sessions?}:::process
F -->|是| G(启动会话session_start()):::process
G --> H(创建会话ID并存储在Cookies):::process
H --> I(后续请求携带会话ID):::process
I --> J(服务器根据会话ID加载数据):::process
F -->|否| K(无状态请求):::process
通过以上内容,我们对Cookies和Sessions有了更深入的了解,在实际开发中可以根据具体需求选择合适的技术来实现用户信息的存储和管理。
深入理解Cookies、Sessions与访问控制
9. 利用Cookies和Sessions实现用户登录系统
现在我们结合Cookies和Sessions来实现一个简单的用户登录系统,步骤如下:
- 用户登录页面 :用户输入用户名和密码,提交表单到验证脚本。
- 验证脚本 :验证用户名和密码是否正确,如果正确则启动会话并设置相关会话变量。
- 后续页面 :在后续页面中检查会话变量,判断用户是否已登录。
以下是具体代码实现:
登录页面(login.php)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login</title>
</head>
<body>
<form action="verify.php" method="post">
<label for="username">Username:</label>
<input type="text" id="username" name="username" required><br>
<label for="password">Password:</label>
<input type="password" id="password" name="password" required><br>
<input type="submit" value="Login">
</form>
</body>
</html>
验证脚本(verify.php)
<?php
// 模拟用户数据库
$users = [
'user1' => 'password1',
'user2' => 'password2'
];
$username = $_POST['username'];
$password = $_POST['password'];
if (isset($users[$username]) && $users[$username] === $password) {
session_start();
$_SESSION['username'] = $username;
setcookie('logged_in', '1', time() + 3600 * 24 * 30); // 设置Cookies表示用户已登录
header('Location: dashboard.php');
exit;
} else {
echo 'Invalid username or password.';
}
仪表盘页面(dashboard.php)
<?php
session_start();
if (!isset($_SESSION['username'])) {
header('Location: login.php');
exit;
}
echo "Welcome, {$_SESSION['username']}! This is your dashboard.";
10. 访问控制与权限管理
在网站开发中,除了实现用户登录,还需要进行访问控制和权限管理。例如,某些页面只有管理员才能访问,我们可以通过会话变量来实现:
<?php
session_start();
// 假设管理员用户名为 'admin'
if ($_SESSION['username']!== 'admin') {
header('Location: dashboard.php');
exit;
}
echo "Welcome, admin! This is the admin dashboard.";
11. 总结与最佳实践
在使用Cookies和Sessions时,以下是一些总结和最佳实践:
| 技术 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| Cookies | 设置简单,可在客户端存储少量信息,可用于跟踪用户行为 | 数量和大小受限,存在安全风险,可能影响性能 | 存储用户偏好设置、访问次数统计等少量信息 |
| Sessions | 可存储大量数据,安全性较高,能为每个用户单独管理会话 | 需要服务器端存储,配置相对复杂 | 存储用户登录状态、购物车信息等大量数据 |
-
安全方面
- 对于敏感信息,如密码,不要存储在Cookies中。
-
使用
httponly和secure参数增强Cookies的安全性。 - 定期更新会话ID,防止会话劫持。
-
性能方面
- 尽量减少Cookies的数量和大小,避免不必要的数据传输。
- 合理设置会话过期时间,避免占用过多服务器资源。
12. 未来发展与注意事项
虽然Cookies和Sessions在目前的网站开发中广泛使用,但也面临一些挑战和未来发展趋势:
- 隐私问题 :随着用户对隐私保护的关注度不断提高,浏览器对Cookies的限制可能会更加严格。开发者需要更加谨慎地使用Cookies,确保用户信息的安全和隐私。
- 技术更新 :未来可能会出现更加安全、高效的用户信息存储和管理技术,开发者需要不断学习和跟进。
以下是一个简单的流程图,展示了用户登录和访问控制的整体流程:
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
A([用户访问网站]):::startend --> B{是否登录?}:::process
B -->|否| C(显示登录页面):::process
C --> D(用户输入用户名和密码):::process
D --> E(验证用户名和密码):::process
E -->|验证成功| F(启动会话,设置会话变量):::process
F --> G(设置Cookies表示已登录):::process
G --> H(重定向到仪表盘页面):::process
E -->|验证失败| C
B -->|是| I{是否有权限访问页面?}:::process
I -->|是| J(显示页面内容):::process
I -->|否| K(重定向到无权限页面):::process
通过深入理解Cookies和Sessions的原理、使用方法以及相关的访问控制技术,开发者可以更好地实现网站的用户登录和管理功能,提高网站的安全性和用户体验。在实际开发中,要根据具体需求合理选择和使用这两种技术,并遵循最佳实践,以应对不断变化的技术环境和用户需求。
Cookies与Sessions深度解析
超级会员免费看
60

被折叠的 条评论
为什么被折叠?



