基于PHP实现JWT登录鉴权的示例代码
目录
- 一、什么是JWT
- 1、简介
- 2、JWT的组成
- 3、JWT验证流程和特点
- 二、相关问题
- 三、PHP实现
- 1、引入依赖
- 2、功能实现
- 3、封装工具类如下
一、什么是JWT
1、简介
JWT(JSON Web Token)是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准。
简单的说,JWT就是一种Token的编码算法,服务器端负责根据一个密码和算法生成Token,然后发给客户端,客户端只负责后面每次请求都在HTTP header里面带上这个Token,服务器负责验证这个Token是不是合法的,有没有过期等,并可以解析出subject和claim里面的数据。
2、JWT的组成
第一部分为头部(header),第二部分我们称其为载荷(payload),第三部分是签证(signature)。【中间用 . 分隔】
一个标准的JWT生成的token格式如下:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImp0aSI6IjRmMWcyM2ExMmFhMTEifQ.eyJpc3MiOiJodHRwOlwvXC9leGFtcGxlLmNvbSIsImF1ZCI6Imh0dHA6XC9cL2V4YW1wbGUub3JnIiwianRpIjoiNGYxZzIzYTEyYWExMSIsImlhdCI6MTY0MDE3MTA1MywibmJmIjoxNjQwMTcxMDU0LCJleHAiOjE2NDAxNzQ2NTMsInVpZCI6MjAsInVzZXJuYW1lIjoiTWFrZSJ9.bysUwNIyhqqEyL0JecSHdplSTfE6G6zuCsrAn6eyrQM
使用https://jwt.io/这个网站对JWT Token进行解析的结果如下
文章图片
3、JWT验证流程和特点
验证流程:
① 在头部信息中声明加密算法和常量, 然后把header使用json转化为字符串
② 在载荷中声明用户信息,同时还有一些其他的内容;再次使用json 把载荷部分进行转化,转化为字符串
③ 使用在header中声明的加密算法和每个项目随机生成的secret来进行加密, 把第一步分字符串和第二部分的字符串进行加密, 生成新的字符串。词字符串是独一无二的。
④ 解密的时候,只要客户端带着JWT来发起请求,服务端就直接使用secret进行解密。
特点:
① 三部分组成,每一部分都进行字符串的转化
② 解密的时候没有使用数据库,仅仅使用的是secret进行解密
③ JWT的secret千万不能泄密!
④ 不依赖数据库,而是直接根据token取出保存的用户信息,以及对token可用性校验,校验方式更加简单便捷化,单点登录更为简单。
【基于PHP实现JWT登录鉴权的示例代码】
二、相关问题
- JWT Token需要持久化在redis、Memcached中吗?
- 在退出登录时怎样实现JWT Token失效呢?
- 怎样保持客户端长时间保持登录状态?
三、PHP实现
1、引入依赖
composer require lcobucci/jwt 3.*
2、功能实现
- 签发token, 设置签发人、接收人、唯一标识、签发时间、立即生效、过期时间、用户id、用户username、签名。其中,用户id、用户username是特意存储在token中的信息,也可以增加一些其他信息,这样在解析的时候就可以直接获取到这些信息,不能是敏感数据
- 验证令牌验证这个Token是不是合法的,有没有过期等,并可以解析出subject和claim里面的数据,传递jwt token的方式为Authorization中的Bearer Token,如下
文章图片
3、封装工具类如下
builder()->issuedBy($this->issuer) // Configures the issuer (iss claim)->permittedFor($this->audience) // Configures the audience (aud claim)->identifiedBy($this->id, true) // Configures the id (jti claim), replicating as a header item->issuedAt($time) // Configures the time that the token was issue (iat claim)->canOnlyBeUsedAfter($time + 1) // Configures the time that the token can be used (nbf claim)签发x秒钟后生效->expiresAt($time + 3600) // Configures the expiration time of the token (exp claim)->withClaim('uid', 20) // Configures a new claim, called "uid"->withClaim('username', "Make") // Configures a new claim, called "uid"->getToken($config->signer(), $config->signingKey()); // Retrieves the generated tokenreturn $token->toString(); }/*** 验证 jwt token 并返回其中的用户id* verify token*/public function verifyToken_bak($token){try {$config = self::getConfig(); assert($config instanceof Configuration); $token = $config->parser()->parse($token); assert($token instanceof Plain); //Lcobucci\JWT\Validation\Constraint\IdentifiedBy: 验证jwt id是否匹配//Lcobucci\JWT\Validation\Constraint\IssuedBy: 验证签发人参数是否匹配//Lcobucci\JWT\Validation\Constraint\PermittedFor: 验证受众人参数是否匹配//Lcobucci\JWT\Validation\Constraint\RelatedTo: 验证自定义cliam参数是否匹配//Lcobucci\JWT\Validation\Constraint\SignedWith: 验证令牌是否已使用预期的签名者和密钥签名//Lcobucci\JWT\Validation\Constraint\StrictValidAt: ::验证存在及其有效性的权利要求中的iat,nbf和exp(支持余地配置//Lcobucci\JWT\Validation\Constraint\LooseValidAt: 验证的权利要求iat,nbf和exp,当存在时(支持余地配置)//验证jwt id是否匹配$validate_jwt_id = new IdentifiedBy($this->id); //验证签发人url是否正确$validate_issued = new IssuedBy($this->issuer); //验证客户端url是否匹配$validate_aud = new PermittedFor($this->audience); $config->setValidationConstraints($validate_jwt_id, $validate_issued, $validate_aud); $constraints = $config->validationConstraints(); if (!$config->validator()->validate($token, ...$constraints)) {die("token invalid!"); }} catch (\Exception $e) {die("error:" . $e->getMessage()); }$jwtInfo = $token->claims(); // 这是jwt token中存储的所有信息return $jwtInfo->get("uid"); // 获取uid}/*** 加密解密使用的配置* @return Configuration*/public static function getConfig(){$configuration = Configuration::forSymmetricSigner(// You may use any HMAC variations (256, 384, and 512)new Sha256(),// replace the value below with a key of your own!InMemory::base64Encoded(self::$key)// You may also override the JOSE encoder/decoder if needed by providing extra arguments here); return $configuration; }/*** 另一种验证方法,但是已经弃用* verify token*/public function verifyToken($token){$token = (new Parser())->parse((string)$token); //验证token$data = https://www.it610.com/article/new ValidationData(); $data->setIssuer($this->issuer); //验证的签发人$data->setAudience($this->audience); //验证的接收人$data->setId($this->id); //验证token标识if (!$token->validate($data)) {//token验证失败die("token invalid!"); }$jwtInfo = $token->claims(); // 这是jwt token中存储的所有信息return $jwtInfo->get("uid"); // 获取uid}}
以上就是基于PHP实现JWT登录鉴权的示例代码的详细内容,更多关于PHP JWT登录鉴权的资料请关注脚本之家其它相关文章!
推荐阅读
- 基于PHP实现个人博客网站
- Spring|Spring Cloud Azure 4.0 GA – 实现 Spring 框架与 Azure 服务的无缝集成
- android应用开发-从设计到实现 3-8 静态原型的Appbar折叠
- Android 7.1.1 之实现 3D Touch
- 设计一款基于内容的推荐系统的简单思路
- python如何检测音乐开始(详细实现指南)
- 有监督学习教程(Python随机森林示例和实现代码)
- 填坑实录Android Studio 利用 ADB WIFI 插件实现真机无线调试
- Android弹幕实现(基于B站弹幕开源系统-重构)
- Vue|Vue 组件实战