Cookie、Session、Token概念、区别、如何实现

Cookie、Session、Token概念以及区别

引言

在互联网世界中,Web应用程序的安全性至关重要。在用户与服务器之间传输敏感信息时,确保用户身份的安全性、用户在系统中的状态追踪以及安全授权变得至关重要。为了应对这些问题,HTTP-Cookie、Session和Token出现并被广泛应用。

概念

Cookie(概念)

Cookie 是一种技术,用于在客户端(通常是浏览器)和服务器之间存储和传递数据。它通过在客户端的浏览器中存储一小段文本数据,来实现在用户多次请求中保持状态的功能。

当服务器返回响应时,通过在响应头中设置 Set-Cookie 报头,将 Cookie 发送给客户端。客户端会将 Cookie 存储在浏览器的内存或硬盘中,以备将来的请求使用。

当客户端再次发起请求时,浏览器会自动将相应的 Cookie 信息添加到请求头的 Cookie 报头中发送给服务器。服务器可以根据请求中的 Cookie 信息来识别和追踪用户,实现用户状态的管理。

Cookie 技术主要用于:

  • 身份验证:保存用户登录状态,实现持久登录。
  • 会话管理:追踪用户的会话信息,例如购物车内容。
  • 个性化设置:存储用户偏好设置,以提供个性化的用户体验。

Cookie 的相关操作和属性可以通过 JavaScript 的 document.cookie 对象进行访问和修改。可以设置 Cookie 的过期时间、作用域、路径等属性,以控制其有效性和访问范围。

Session(概念)

Session(会话)是一种在服务器端存储用户状态和数据的机制。它通过在服务器端创建一个唯一的会话标识(通常是一个 Session ID),并将该标识发送给客户端,实现在不同的请求中跟踪和管理用户的状态。

当用户访问一个网站时,服务器会为该用户创建一个会话,并将会话 ID 存储在 Cookie 中,或者通过其他方式将其发送给客户端。客户端的浏览器会自动在后续的请求中将会话 ID 发送给服务器,在服务器端找到对应的会话数据。

会话数据存储在服务器端的临时存储区域,通常是在服务器的内存中或在数据库中。服务器会根据会话 ID 来检索和更新相应的数据,从而实现用户状态的管理和维护。

Session 技术的主要作用:

  • 身份验证:存储用户登录信息和权限,实现用户认证。
  • 会话管理:追踪用户的操作和活动,在请求之间保持连续性。
  • 数据存储:存储用户数据,例如购物车、表单数据等。

需要注意的是,为了保护用户数据的安全性和隐私,开发人员应采取适当的安全措施:

  • 使用安全的传输协议(如 HTTPS)来保护会话数据在网络传输中的安全性。
  • 针对会话 ID 的保护,包括生成安全的随机会话 ID、设置合适的过期时间,以及通过 HttpOnly 和 Secure 标志来防止跨站脚本攻击和会话劫持。

Token(概念)

Token(令牌)是一种在身份验证和授权中使用的字符串,用于验证客户端的身份和权限。它作为客户端和服务器之间进行安全通信的一种方式,来确保用户的身份和访问权限。

Token 的主要特点是它是无状态的,即服务器不需要在存储设备中维护任何信息。服务器在生成 Token 后,将其发送给客户端,客户端在以后的请求中将 Token 作为身份凭证发送给服务器。服务器通过验证 Token 的有效性,来确认客户端的身份和权限。

Token 的生成和验证过程一般包含以下步骤:

  1. 客户端向服务器发送身份验证请求,通常是提供用户名和密码。
  2. 服务器验证客户端提供的身份信息,并生成一个 Token
  3. 服务器将生成的 Token 发送给客户端,客户端将其保存。
  4. 客户端在以后的请求中将 Token 添加到请求头中,作为身份凭证。
  5. 服务器在接收到请求时,验证 Token 的有效性和权限,并相应地处理请求。

Token 的主要作用:

  • 身份验证:通过 Token 来验证客户端的身份,替代传统的基于会话的身份验证机制,不需要在服务器端存储会话信息,减轻服务器的负担。
  • 授权:服务器可以根据 Token 中的信息来判断客户端的权限,决定是否允许相应的操作。
  • 单点登录(SSO):Token 可以在不同的应用程序之间共享,实现用户的单点登录功能。

Token 可以有不同的类型和格式,常见的包括 JSON Web Token(JWT)、OAuth 2.0 的访问令牌等。同时,Token 也可以通过加密和签名等方式来保证其安全性。

概念总结

·Cookie

  • Cookie 是在客户端存储数据的机制,由服务器通过 Set-Cookie 响应头发送给客户端浏览器,并存储在客户端上。
  • 主要用于在客户端保持用户状态和存储少量数据。
  • 存储在客户端,可能存在安全风险和受限制的存储容量。

Session

  • Session 是在服务器端存储用户状态和数据的机制,通过为每个客户端创建唯一的会话标识来进行管理。
  • 主要用于在服务器上跟踪用户、存储大量数据和实现身份认证。
  • 存储在服务器端,安全性较高,但会增加服务器的负担和存储需求。

Token

  • Token 是在客户端和服务器之间传递信息的机制,作为身份验证和授权的凭证。
  • 主要用于跨域身份认证、无状态 API 认证和授权。
  • 可以存储在客户端或服务器端,需要一定的安全措施来保护传输和存储。

Cookie 是一种在客户端存储数据的机制,用于在客户端保持用户状态;

Session 是一种在服务器端存储用户状态和数据的机制,用于跟踪用户和存储大量数据;

Token 是一种在客户端和服务器之间传递信息的机制,用于身份认证和授权。

Cookie、session、Token的区别

Cookie、Session 和 Token 是用于在 Web 应用程序中处理用户身份验证和状态管理的不同机制,它们在以下几个方面有所区别:

  1. 存储位置:
  • Cookie:存储在客户端浏览器中,作为浏览器的一部分。
  • Session:存储在服务器端,通常存储在服务器的内存或数据库中。
  • Token:可以存储在客户端或服务器端,具体取决于实际实现。
  1. 安全性:
  • Cookie:存储在客户端,容易受到劫持和篡改的风险。
  • Session:数据存储在服务器端,相对较安全。但仍然需要防止会话劫持攻击等安全问题。
  • Token:需要建立安全的传输通道和存储机制,确保传输中的数据安全性。
  1. 实现复杂性:
  • Cookie:简单易用,浏览器自动处理 Cookie 的创建、存储和发送。
  • Session:需要服务器端存储和管理 Session 数据,设计和实现复杂一些。
  • Token:可以在服务器端或客户端自行实现,可以更加灵活但也需要更多的开发工作。
  1. 传递数据量大小:
  • Cookie:有大小限制,一般为 4KB 左右。
  • Session:可存储较大量的数据,不受 Cookie 大小限制。
  • Token:通常只包含身份验证和授权所需的信息,通常比较小。
  1. 跨域问题:
  • Cookie:由于同源策略的限制,在跨域请求时 Cookie 不会自动发送,需要进行一些额外的配置。
  • Session:通常通过 Cookie 的方式存储 Session ID,在跨域请求时需要考虑如何处理 Session ID。
  • Token:可以更方便地进行跨域身份验证,通过在请求头中添加 Token 进行传递。
  1. 无状态性:
  • Cookie:无状态,每次请求都会将所有的 Cookie 数据发送给服务器。
  • Session:需要在服务器端维护会话状态,具有一定的状态保存能力。
  • Token:无状态,服务器根据 Token 验证和处理请求,不需要在服务器端保存会话状态。

综上所述,Cookie、Session 和 Token 在存储位置、安全性、实现复杂性和数据传输等方面有所区别,开发人员需要根据具体的需求和安全要求来选择合适的机制。

Cookie、Session、Token的安全性

Cookie、Session 和 Token 在安全性方面都有一些考虑和措施,但具体的安全性取决于实施的方式和使用环境。以下是它们的安全性考虑:

Cookie 的安全性:

  • Cookie 存储在客户端,容易受到劫持和篡改的风险,因此需要一些安全措施:
    • 使用安全标志(Secure Flag):设置 Cookie 的 Secure Flag,确保只在加密的 HTTPS 连接中传输。
    • 设置 HttpOnly 属性:设置 Cookie 的 HttpOnly 属性,防止恶意脚本通过 JavaScript 访问 Cookie。
    • 设置 SameSite 属性:使用 SameSite 属性限制跨站点请求中 Cookie 的发送,减少 CSRF 攻击的风险。
    • 加密敏感数据:在 Cookie 中保存敏感信息时,应使用加密算法对数据进行加密。

Session 的安全性:

  • Session 数据存储在服务器端,相对较安全,但仍然需要考虑以下安全问题:
    • Session ID 管理:生成安全的随机 Session ID,确保其难以被猜测或预测。
    • 安全传输:在传输过程中使用加密的协议(如 HTTPS)来保护 Session ID 的安全传输。
    • 过期处理:设置适当的 Session 过期时间,确保会话不会无限期存在。
    • 防止会话劫持:可以使用令牌或其他方式在每个请求中验证会话的合法性,防止会话劫持攻击。

Token 的安全性:

  • Token 的安全性主要取决于令牌的生成、传输和验证过程:
    • 随机生成:生成安全的随机令牌,确保令牌的复杂度和猜测性。
    • 安全传输:在令牌传输过程中使用加密的通道(如 HTTPS)来保护令牌的安全。
    • 验证令牌:服务器需要验证令牌的签名和有效性,确保令牌未被篡改或伪造。
    • 注销和刷新:提供注销令牌和刷新令牌的机制,以及设置令牌过期时间,确保令牌的安全和有效性。

Cookie的实现

在实现 Cookie 的过程中,通常需要涉及以下步骤:

  1. 服务器端设置 Cookie:

    • 当服务器接收到客户端的请求时,根据需要生成 Cookie。
    • 在响应头中设置 Set-Cookie 报头,包括 Cookie 的名称和值,以及其他属性如过期时间、域名、路径等。
    • 发送响应给客户端,将 Cookie 信息发送到客户端浏览器。
  2. 客户端存储 Cookie:

    • 客户端浏览器在接收到服务器的响应后,会自动将 Set-Cookie 报头中的 Cookie 信息存储在 Cookie 存储中,保存在客户端。
  3. 客户端发送 Cookie:

    • 当客户端发起后续的请求时,浏览器会自动将相应的 Cookie 信息包含在请求头的 Cookie 报头中发送给服务器。
    • 服务器可以通过读取请求头中的 Cookie 报头来获取客户端发送的 Cookie 信息。
  4. 服务器端处理 Cookie:

    • 服务器端可以通过读取请求的 Cookie 报头来获取客户端发送的 Cookie 信息,并根据需要进行处理,如判断用户的登录状态、进行身份验证等。
    • 服务器还可以发送新的 Set-Cookie 报头来更新或删除客户端的 Cookie,以实现会话管理、登录状态的维护等。

PHP代码实现

  1. 设置 Cookie:
// 在服务器端设置一个名为 "myCookie" 的 Cookie,有效期为 1 小时
setcookie("myCookie", "cookie value", time()+3600);
  1. 读取 Cookie:
// 检查是否存在名为 "myCookie" 的 Cookie,并读取其值
if (isset($_COOKIE['myCookie'])) {
    
    
    $cookieValue = $_COOKIE['myCookie'];
    echo "Cookie value is: " . $cookieValue;
} else {
    
    
    echo "Cookie not found";
}
  1. 更新 Cookie:
// 更新名为 "myCookie" 的 Cookie 的值和有效期
setcookie("myCookie", "new value", time()+3600);
  1. 删除 Cookie:
// 删除名为 "myCookie" 的 Cookie
setcookie("myCookie", "", time()-3600);

需要注意的是,对于 setcookie() 函数,应该在发送任何输出之前调用,以确保在响应头中正确设置 Cookie。

此外,可以使用其他可选的参数来设置 Cookie 的过期时间、路径、域等属性,例如:

setcookie("myCookie", "cookie value", time()+3600, "/", ".example.com", true, true);

通过指定以上参数,可以按需设置 Cookie 的有效期、访问路径、域名、安全标志等。

javaScript实现Cookie

  1. 设置 Cookie:
// 在客户端设置一个名为 "myCookie" 的 Cookie,有效期为1小时
document.cookie = "myCookie=cookie value; expires=" + new Date(new Date().getTime() + 3600000).toUTCString();
  1. 读取 Cookie:
// 读取名为 "myCookie" 的 Cookie
var cookieValue = document.cookie.replace(/(?:(?:^|.*;\s*)myCookie\s*=\s*([^;]*).*$)|^.*$/, "$1");

if (cookieValue) {
    
    
    console.log("Cookie value is: " + cookieValue);
} else {
    
    
    console.log("Cookie not found");
}
  1. 更新 Cookie:
// 更新名为 "myCookie" 的 Cookie 的值和有效期
document.cookie = "myCookie=new value; expires=" + new Date(new Date().getTime() + 3600000).toUTCString();
  1. 删除 Cookie:
// 删除名为 "myCookie" 的 Cookie
document.cookie = "myCookie=; expires=" + new Date(0).toUTCString();

需要注意的是,在 JavaScript 中使用 document.cookie 设置和读取 Cookie 时,需要注意 Cookie 的格式和编码,以确保正确处理特殊字符和值。

另外,为了提高 Cookie 的安全性,可以通过设置路径和域来限制 Cookie 的可访问范围,例如:

document.cookie = "myCookie=cookie value; expires=" + new Date(new Date().getTime() + 3600000).toUTCString() + "; path=/; domain=.example.com; secure";

通过指定以上参数,可以按需设置 Cookie 的有效期、访问路径、域名和安全标志。

Session的实现

  1. 服务器端创建 Session:

    • 当客户端发送请求时,服务器端会检查请求中是否包含会话标识,通常是通过 Cookie 的方式将会话标识(Session ID)发送给客户端。
    • 服务器在接收到请求后,根据会话标识检查是否存在与之关联的会话数据。
      • 如果存在会话数据,则继续使用该会话。
      • 如果不存在会话数据,则在服务器端创建一个新的会话,并生成一个唯一的会话标识(Session ID)。
  2. 服务器端存储和管理 Session 数据:

    • 在服务器端,会话数据通常会存储在内存或持久化存储(如数据库)中。
    • 服务器将会话标识和对应的会话数据相关联,并进行存储或更新。
  3. 服务器端响应中设置会话标识:

    • 当服务器返回响应时,会将会话标识发送给客户端,通常是通过设置 Cookie 的方式,将会话标识作为 Cookie 的值发送给客户端浏览器。
    • 在响应头中设置 Set-Cookie 报头,指定会话标识的名称、值以及其他属性如过期时间、域名、路径等。
  4. 客户端发送会话标识:

    • 当客户端发送后续的请求时,浏览器会自动将会话标识作为 Cookie 放入请求头中的 Cookie 报头中,随请求一起发送给服务器。
  5. 服务器端验证和获取会话数据:

    • 服务器接收到请求后,会通过读取请求头中的 Cookie 报头,获取客户端发送的会话标识。
    • 根据会话标识,服务器查找对应的会话数据,并进行验证和获取。

PHP实现Session

  1. 启动 Session:
// 启动或恢复已存在的会话
session_start();
  1. 设置 Session 数据:
// 设置session中的数据
$_SESSION['username'] = 'JohnDoe';
$_SESSION['email'] = '[email protected]';
  1. 读取 Session 数据:
// 读取session中的数据
$username = $_SESSION['username'];
$email = $_SESSION['email'];
  1. 更新 Session 数据:
// 更新session中的数据
$_SESSION['username'] = 'JaneDoe';
  1. 删除 Session 数据:
// 删除session中的特定数据
unset($_SESSION['email']);
  1. 结束 Session:
// 结束当前会话并删除所有会话数据
session_unset();  // 清空 session
session_destroy();  // 销毁 session

session_start() 函数应该在发送任何输出之前调用,以确保正确启动会话。另外,PHP 默认将会话数据存储在服务器的临时目录中,可以通过设置 session_save_path() 函数来更改默认存储位置。

javaScript 实现session

  1. 使用 localStoragesessionStorage
    可以使用 Web Storage API(localStoragesessionStorage)来存储会话相关的数据。这些 API 可以在浏览器中的客户端存储数据,并且在多个页面之间共享。
// 设置会话数据
localStorage.setItem('username', 'JohnDoe');
localStorage.setItem('email', '[email protected]');

// 读取会话数据
const username = localStorage.getItem('username');
const email = localStorage.getItem('email');

// 删除会话数据
localStorage.removeItem('email');
  1. 使用客户端存储对象:
    你可以在客户端使用 JavaScript 对象来存储会话数据。这种方式的缺点是数据在页面刷新时会丢失。
// 设置会话数据
const sessionData = {
    
    
  username: 'JohnDoe',
  email: '[email protected]'
};

// 读取会话数据
const username = sessionData.username;
const email = sessionData.email;

// 删除会话数据
delete sessionData.email;
  1. 使用 Cookie:
    虽然 JavaScript 可以通过 document.cookie 设置和读取 Cookie,但由于 Cookie 的大小和数量限制,并不适合存储大量的会话数据。

如果你想在 JavaScript 中模拟会话的全局访问以及在多个页面之间共享会话数据,你可以结合使用 localStoragesessionStorage 和 Cookie,使用 Cookie 存储会话标识符,而实际的会话数据存储在 localStoragesessionStorage 中。

下面是基于这种方式的示例:

// 生成会话标识符并保存到 Cookie
const sessionId = 'abc123';
document.cookie = `sessionId=${
      
      sessionId}; path=/`;

// 存储会话数据到 localStorage 或 sessionStorage
localStorage.setItem(sessionId, JSON.stringify({
    
    
  username: 'JohnDoe',
  email: '[email protected]'
}));

// 读取会话数据
const sessionData = JSON.parse(localStorage.getItem(sessionId));
const username = sessionData.username;
const email = sessionData.email;

// 删除会话数据
localStorage.removeItem(sessionId);

Token的实现

在实现 Token 的过程中,通常需要涉及以下步骤:

  1. 服务器端生成 Token:

    • 当客户端发送身份验证请求时,服务器进行身份验证,验证成功后,生成一个 Token。
    • Token 的生成可以使用加密算法,例如 HMAC 或 RSA,生成一个唯一的、随机的字符串。
  2. 服务器端绑定 Token 和用户信息:

    • 服务器在生成 Token 后,将 Token 和相关的用户信息进行绑定,并存储在服务器端的缓存或数据库中。
    • 绑定的信息可以包括用户 ID、角色或权限等。
  3. 服务器端发送 Token 给客户端:

    • 当服务器端生成 Token 并与用户信息绑定后,将 Token 发送给客户端,通常是在响应的报文中作为响应数据返回给客户端。
  4. 客户端存储 Token:

    • 客户端接收到服务器返回的 Token 后,将 Token 存储在客户端,可以使用浏览器的本地存储(如 sessionStorage 或 localStorage)或内存中的变量进行存储。
  5. 客户端发送 Token 给服务器:

    • 当客户端发起后续的请求时,将 Token 添加到请求头的 Authorization 报头中,作为身份凭证发送给服务器。
    • 报头可以采用形如 Authorization: Bearer <Token> 的格式,其中 <Token> 是实际的 Token 值。
  6. 服务器端验证 Token:

    • 服务器在接收到请求时,从请求头的 Authorization 报头中提取 Token。
    • 服务器使用相同的加密算法和密钥验证和解析 Token,以验证其合法性和有效性。
    • 如果 Token 验证通过,则解析 Token 得到相关的用户信息,并进行相应的处理。
    • php实现Token

      1. 安装依赖:
        首先,你需要使用 Composer 安装 PHP JWT 库,例如 firebase/php-jwt
    composer require firebase/php-jwt
    
  7. 生成 Token:

// 导入需要的类和方法
require __DIR__ . '/vendor/autoload.php';

use \Firebase\JWT\JWT;

// 设置 payload 数据
$payload = array(
    "user_id" => 123,
    "username" => "john.doe"
);

// 设置密钥和算法
$key = "your_secret_key";
$algorithm = "HS256";

// 生成 Token
$token = JWT::encode($payload, $key, $algorithm);

// 输出 Token
echo $token;
  1. 验证 Token:
// 导入需要的类和方法
require __DIR__ . '/vendor/autoload.php';

use \Firebase\JWT\JWT;

// 设置密钥
$key = "your_secret_key";

// 要验证的 Token
$token = "your_token_here";

try {
    
    
    // 验证并解析 Token
    $decoded = JWT::decode($token, $key, array('HS256'));
    
    // 访问有效载荷中的数据
    echo $decoded->user_id;
    echo $decoded->username;
} catch (Exception $e) {
    
    
    // Token 无效或已过期
    echo $e->getMessage();
}

需要注意的是,这是 JWT 的基本用法示例,可以根据需要添加更多选项和配置,例如设置过期时间、添加自定义声明等。

javaScript实现token

  1. 安装依赖:
    首先,在你的 JavaScript 项目中安装 JWT 库,如 jsonwebtoken

    npm install jsonwebtoken
    
  2. 生成 Token:

// 导入需要的模块
const jwt = require('jsonwebtoken');

// 设置 payload 数据
const payload = {
    
     user_id: 123, username: 'john.doe' };

// 设置密钥
const secretKey = 'your_secret_key';

// 设置选项
const options = {
    
     expiresIn: '1h' };

// 生成 Token
const token = jwt.sign(payload, secretKey, options);

// 输出 Token
console.log(token);
  1. 验证 Token:
// 导入需要的模块
const jwt = require('jsonwebtoken');

// 要验证的 Token
const token = 'your_token_here';

// 设置密钥
const secretKey = 'your_secret_key';

try {
    
    
    // 验证 Token
    const decoded = jwt.verify(token, secretKey);
    
    // 访问有效载荷中的数据
    console.log(decoded.user_id);
    console.log(decoded.username);
} catch (err) {
    
    
    // Token 无效或已过期
    console.log(err.message);
}

上述示例基于 Node.js 环境,使用了 Node.js 版本的 jsonwebtoken 库。如果你在浏览器端使用 JavaScript 来生成和验证 Token,则需要使用浏览器支持的 JWT 库,例如 jsonwebtoken 的浏览器版本或其他支持 JWT 的库。

猜你喜欢

转载自blog.csdn.net/weixin_44369049/article/details/132062232