作者:GRIROR格雷尔 | 来源:互联网 | 2024-10-26 04:51
本文初步探讨了PHP中基于JWT(JSONWebToken)的身份验证机制。具体流程包括:1.客户端通过用户名和密码发起登录请求;2.服务器接收并验证用户凭证的合法性,若验证通过,则生成并返回一个JWT令牌;3.客户端接收该令牌,并在后续请求中携带此令牌以完成身份验证。这一机制不仅提高了安全性,还简化了会话管理。
使用token进行身份验证过程
1.客户端使用账号密码进行登录
2.服务端接受到请求后验证账号以及密码的正确性,若正确则服务端回传一个Token
3.客户端接收到Token后对其进行存储,每次访问时需携带token
4.服务端在接受到客户端请求时需验证token有效性,验证成功则回传数据。
生成与验证token的方法有很多种,我们这里使用的是jwt( Json Web Token)。
使用前提
首先使用方法需要在composer.json中引入firebase/php-jwt,之后进行composer安装。
名称 | 解释 |
iss (issuer) | issuer 请求实体,可以是发起请求的用户的信息,也可是jwt的签发者 |
sub (Subject) | 设置主题,类似于发邮件时的主题 |
aud (audience) | 接收jwt的一方 |
exp (expire) | token过期时间 |
nbf (not before) | 当前时间在nbf设定时间之前,该token无法使用 |
iat (issued at) | token创建时间 |
jti (JWT ID) | 对当前token设置唯一标示 |
class JWTTool extends Controller {public function __construct(ContainerInterface $container = null){header("Content-Type: text/html; charset=utf-8");$this->setContainer($container);}private $key = 'DLWYZ';//密钥private $iss = "http://example.org/send";//签发者private $aud = "http://example.org/accept";//接受者/*** @param $data 加密的数据* @param int $is_exp 是否加入有效时间* @param int $time 有效时长* @return string*/public function generateToken($data,$is_exp = 1,$time = 86400){$token['iss'] = $this->iss;$token['aud'] = $this->aud;$token['iat'] = strtotime(date('Y-m-d H:i:s'));if($is_exp){$token['exp'] = strtotime(date('Y-m-d H:i:s'))+$time;}$token['data'] = $data;$jwt = JWT::encode($token, $this->key);//alg,默认使用HS256方式return $jwt;}/*** 验证* @param $jwt* @param $client 平台号* @return array|\Symfony\Component\HttpFoundation\Response*/public function verificationToken($jwt,$client){$key = $this->key; //key要和签发的时候一样try {JWT::$timestamp = strtotime(date('Y-m-d H:i:s'));//当前时间$decoded = JWT::decode($jwt, $key, ['HS256']); //HS256方式,这里要和签发的时候对应if(empty($decoded->data)){throw new Exception('未登录');}if(empty($decoded->data->client)){throw new Exception('非法操作,端口错误');}if($decoded->data->client != $client){throw new Exception('非法操作,端口错误');}return Responses::arrays('登录成功',0,['user_id'=>$decoded->data->user_id]);} catch(\Firebase\JWT\SignatureInvalidException $e) { //签名不正确return Responses::arrays('签名错误',1);}catch(\Firebase\JWT\BeforeValidException $e) { //return Responses::arrays($e->getMessage(),1);}catch(\Firebase\JWT\ExpiredException $e) { // token过期return Responses::arrays('登录凭证失效',-1);}catch(Exception $e) { //其他错误return Responses::arrays($e->getMessage());}}public function verificationOther($jwt,$data){$key = $this->key; //key要和签发的时候一样try {JWT::$timestamp = strtotime(date('Y-m-d H:i:s'));//当前时间$decoded = JWT::decode($jwt, $key, ['HS256']); //HS256方式,这里要和签发的时候对应$tag_data = (array)$decoded->data;foreach ($data as $k=>$v){if(!array_key_exists($k,$tag_data)){throw new Exception('验证失败');}if($tag_data[$k] != $data[$k]){throw new Exception('验证失败');}}return Responses::arrays('验证成功',0,$data);} catch(\Firebase\JWT\SignatureInvalidException $e) { //签名不正确return Responses::arrays('签名错误');}catch(\Firebase\JWT\BeforeValidException $e) { //return Responses::arrays($e->getMessage());}catch(\Firebase\JWT\ExpiredException $e) { // token过期return Responses::arrays('凭证失效',1);}catch(Exception $e) { //其他错误return Responses::arrays($e->getMessage());}}}