淄博网站优化推广,优秀网站ui设计,wordpress 制作瀑布流,柬埔寨网站建设运营维护概述
登录功能是对于每个动态系统来说都是非常基础的功能#xff0c;用以区别用户身份、和对应的权限和信息#xff0c;设计出一套安全的登录方案尤为重要#xff0c;接下来我介绍一下常见的认证机制的登录设计方案。
方案设计
HTTP 是一种无状态的协议#xff0c;客户端…概述
登录功能是对于每个动态系统来说都是非常基础的功能用以区别用户身份、和对应的权限和信息设计出一套安全的登录方案尤为重要接下来我介绍一下常见的认证机制的登录设计方案。
方案设计
HTTP 是一种无状态的协议客户端每次发送请求时首先要和服务器端建立一个连接在请求完成后又会断开这个连接。系统登录的本质是确认用户的合法性和身份。
Cookie Session 登录
在 B/S 系统中登录功能通常都是基于 Cookie 来实现的。当用户登录成功后一般会将登录状态记录到 Session 中。要实现服务端对客户端的登录信息进行验证都需要在客户端保存一些信息SessionId并要求客户端在之后的每次请求中携带它们。在这样的场景下使用 Cookie 无疑是最方便的因此我们一般都会将 Session 的 Id 保存到 Cookie 中当服务端收到请求后通过验证 Cookie 中的信息来判断用户是否登录 。
用户首次登录流程 1、用户访问 www.stark.com/login并输入密码登录。 2、服务器验证密码无误后会创建 SessionId并将它保存起来。 3、服务器端响应这个 HTTP 请求并通过 Set-Cookie 头信息将 SessionId 写入 Cookie 中。
cookice后续校验流程
获取cookice后续的访问就可以直接使用 Cookie 进行身份验证了 1、用户访问 www.stark.com/console 页面时会自动带上第一次登录时写入的 Cookie。 2、服务器端比对 Cookie 中的 SessionId 和保存在服务器端的 SessionId 是否一致。 3、如果一致则身份验证成功访问页面如果无效则需要用户重新登录。
需要注意的是: Cookie Session 的方案中最关键的环节是传递Cookie有时可能会面临Cookie禁用的情况记住只要把Cookie的值传递给服务端得到SessionId即可可以是存储在LocalStorage也可以使用URL 的GET方式传输。
Cookie Session 技术实现
Cookie Session的核心点在于数据的加密和解密的算法在用户登录进行加密、生成Cookie,在之后的交互的时候携带在header的信息头中。
加密函数代码:
function passportEncrypt($txt, $key stark-server2024#$!): string
{$txt yy-依加衣- . time() . - . $txt;srand((double)microtime() * 1000000);$encrypt_key md5(rand(0, 32000));// 变量初始化$ctr 0;$tmp ;for ($i 0; $i strlen($txt); $i) {$ctr $ctr strlen($encrypt_key) ? 0 : $ctr;$tmp . $encrypt_key[$ctr] . ($txt[$i] ^ $encrypt_key[$ctr]);}return base64_encode(passportKey($tmp, $key));
}function passportKey($txt, $encrypt_key): string
{$encrypt_key md5($encrypt_key);$ctr 0;$tmp ;for ($i 0; $i strlen($txt); $i) {$ctr $ctr strlen($encrypt_key) ? 0 : $ctr;$tmp . $txt[$i] ^ $encrypt_key[$ctr];}return $tmp;
}字符串解密函数: function passportDecrypt($txt, $key stark-server2024#$!)
{$txt str_replace( , , $txt);$txt passportKey(base64_decode($txt), $key);$tmp ;for ($i 0; $i strlen($txt); $i) {if (!isset($txt[$i]) || !isset($txt[$i 1])) {return 0;} else {$tmp . $txt[$i] ^ $txt[$i];}}$tmp explode(-, $tmp);$tmp[3] $tmp[3] ?? 0;return $tmp[3];
}加密解密实现的具体逻辑:
//加密
$data [admin_id $adminInfo[admin_id],admin_name $adminInfo[admin_name],
];
$demoStr json_encode($data,JSON_UNESCAPED_UNICODE);
$authorization passportEncrypt($demoStr);Cookie::set(Auth-stark, $authorization,[prefix think, expire 3600]
);//解密
$json passportDecrypt($authorization);
if(mb_strlen($json) 0){$demoData json_decode($json,true);
}Token 登录
由于服务器端需要对接大量的客户端也就需要存放大量的 SessionId这样会导致服务器压力过大、无法避免 CSRF 攻击等缺点我们可以使用 Token 的登录方式。
Token是通过服务端生成的一串字符串以作为客户端请求的一个令牌。当第一次登录后服务器会生成一个 Token 并返回给客户端客户端后续访问时只需带上这个 Token 即可完成身份认证很多企业使用JWT的技术来进行登录验证方式。
用户首次登录 1、用户访问 www.stark.com/login输入账号密码并点击登录。 2、服务器端验证账号密码无误创建 Token。 3、服务器端将 Token 返回给客户端由客户端存储在Header头信息里。
后续页面访问 1、用户访问 www.stark.com/login 时带上第一次登录时获取的 Token。 2、服务器端验证该 Token 有效则身份验证成功无效则踢回重新的登录。
Token 生成方式
最常见的 Token 生成方式是使用 JWTJson Web Token它是一种简洁的、自包含的方法用于通信双方之间以 JSON 对象的形式安全的传递信息。
答案其实就在 Token 字符串中其实 Token 并不是一串杂乱无章的字符串而是通过多种算法拼接组合而成的字符串。
JWT 算法主要分为 3 个部分header头信息playload消息体signature签名。
header 部分指定了该 JWT 使用的签名算法playload 部分表明了 JWT 的意图signature 部分为 JWT 的签名主要为了让 JWT 不能被随意篡改。
JWT Token 技术实现
Compose 安装 Jwt 的两种方式,我使用的是6.10版本 :
## 安装
composer require firebase/php-jwt 6.10使用 composer.json 安装加入文件,使用composer install
require: {firebase/php-jwt: ^6.10
}Jwt 主要是进行加密和解密$payload定义的是你需要存储的数组信息
public static function encode(int $adminId 0): string
{$redis new Redis(config(cache.stores.redis));$secretKey Env::get(JWT.key); // 获取JWT生成签名的密钥$alg Env::get(JWT.alg); // 获取JWT加密算法$payload [admin_id $adminId, // 存储用户IDexp time() Env::get(JWT.exp), // 设定过期时间];$jwt JWT::encode($payload, $secretKey, $alg); // 生成JWT令牌$token config(prefix.auth);$redis-set($token.$adminId, $jwt,Env::get(JWT.exp) - rand(10,99));return $jwt;
}解密的逻辑
public static function decode(string $AccessToken ){$secretKey Env::get(JWT.key); // 获取JWT生成签名的密钥$alg Env::get(JWT.alg); // 获取JWT加密算法$secretKeyObj new Key($secretKey,$alg);$headers new stdClass();return JWT::decode($AccessToken, $secretKeyObj,$headers); // 使用JWT解密Token
}