ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

PHP使用JWT实现API身份验证的完整流程

PHP使用JWT实现API身份验证的完整流程 1. JWT简介JWT由三部分组成Header-包含令牌的类型和使用的哈希算法如HMAC SHA256或RSA。Payload-包含声明claims。声明是关于实体通常是用户和其他数据的有三种类型注册声明、公共声明和私有声明。Signature-对前两部分的签名防止数据篡改。例如一个JWT看起来像这样xxxxx.yyyyy.zzzzz三个Base64-URL字符串用点分隔。2. 环境准备在开始之前确保你已经安装了PHP建议7.4以上版本和Composer。我们这里使用firebase/php-jwt库来处理JWT的生成和验证。1composer require firebase/php-jwt3. 用户注册与登录3.1 数据库设计为了简单起见我们使用MySQL数据库。创建一个名为users的表12345CREATETABLEusers (idINTAUTO_INCREMENTPRIMARYKEY,usernameVARCHAR(50)NOTNULLUNIQUE,passwordVARCHAR(255)NOTNULL);注意‌ 密码必须是经过哈希处理用到的是PHP的password_hash()函数。3.2 注册接口在注册接口中我们接收用户名和密码将密码哈希后存储到数据库。123456789101112131415161718192021?phprequirevendor/autoload.php;useFirebase\JWT\JWT;// 连接数据库$pdonewPDO(mysql:hostlocalhost;dbnametest,root,password);functionregister($username,$password) {global$pdo;// 检查用户名是否已存在$stmt$pdo-prepare(SELECT id FROM users WHERE username ?);$stmt-execute([$username]);if($stmt-fetch()) {return[errorUser already exists];}// 哈希密码$hash password_hash($password, PASSWORD_DEFAULT);$stmt$pdo-prepare(INSERT INTO users (username, password) VALUES (?, ?));$stmt-execute([$username,$hash]);return[messageUser registered successfully];}3.3 登录接口登录时验证用户名和密码如果正确则生成JWT令牌返回给客户端。123456789101112131415161718192021222324functionlogin($username,$password) {global$pdo;$stmt$pdo-prepare(SELECT id, password FROM users WHERE username ?);$stmt-execute([$username]);$user$stmt-fetch();if(!$user|| !password_verify($password,$user[password])) {return[errorInvalid credentials];}// 生成JWT$secret_keyyour_secret_key;// 应该是一个复杂的随机字符串存储在环境变量中$payload [isslocalhost,// 签发者audlocalhost,// 接收方iat time(),// 签发时间exp time() 3600,// 过期时间1小时data [user_id$user[id],username$username]];$jwt JWT::encode($payload,$secret_key,HS256);return[token$jwt];}4. 验证JWT在需要身份验证的API例如用户个人信息接口中我们需要验证客户端传来的JWT。12345678910111213141516171819202122functiongetProfile() {// 获取Authorization头$headersgetallheaders();if(!isset($headers[Authorization])) {http_response_code(401);return[errorToken not provided];}$tokenstr_replace(Bearer ,,$headers[Authorization]);$secret_keyyour_secret_key;try{$decoded JWT::decode($token,newFirebase\JWT\Key($secret_key,HS256));// 如果验证成功$decoded将包含我们之前设置的payload$user_id$decoded-data-user_id;// 现在可以根据user_id从数据库获取用户信息并返回// ... 数据库查询代码 ...return[user$userInfo];}catch(Exception$e) {http_response_code(401);return[errorInvalid token];}}5. 安全性考虑‌使用HTTPS‌在传输过程中保护JWT防止被截获。‌密钥安全‌密钥secret_key必须足够复杂且不要硬编码在代码中应该使用环境变量。‌令牌过期‌设置合理的过期时间如1小时并考虑使用刷新令牌机制来延长会话。‌存储方式‌客户端通常将JWT存储在localStorage或sessionStorage中但要注意XSS攻击。也可以使用HttpOnly的Cookie来存储避免XSS但要注意CSRF防护。6. 总结通过本文我们学习了如何在PHP中使用JWT进行API身份验证。从用户注册登录到JWT的生成与验证我们实现了一套完整的流程。JWT提供了一种无状态的认证机制非常适合分布式应用和前后端分离架构。当然安全是一个持续的过程除了本文介绍的内容我们平时开发的时候还是需要关注其他安全措施比如常见的输入验证、基础防止SQL注入等。
返回列表