JWT
1. JSON Web Token是什么
JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。
2.什么时候你应该用JSON Web Token
- Authorization (授权) : 这是使用JWT的最常见场景。一旦用户登录,后续每个请求都将包含JWT,允许用户访问该令牌允许的路由、服务和资源。单点登录是现在广泛使用的JWT的一个特性,因为它的开销很小,并且可以轻松地跨域使用。
- Information Exchange (信息交换) : 对于安全的在各方之间传输信息而言,JSON Web Tokens无疑是一种很好的方式。因为JWT可以被签名,例如,用公钥/私钥对,你可以确定发送人就是它们所说的那个人。另外,由于签名是使用头和有效负载计算的,您还可以验证内容没有被篡改。
3.JWT结构
JSON Web Token由三部分组成,它们之间用圆点(.)连接。这三部分分别是:
- Header(头部)
- Payload(负载)
- Signature(签名)
格式:
xxxxx.yyyyy.zzzzz
4.JWT验证机制
个人理解:
成功登陆账号密码获取jwt值
根据jwt值完成授权
Conposer安装JWT:
composer require lcobucci/jwt 3.3
上代码:
//创建控制器
php think make:controller Demo php think make:controller BaseApi
//创建验证器
php think make:validate Login
Demo继承BaseApi控制器
BaseApi控制器:
<?php namespace app\textapi\controller; use Lcobucci\JWT\Builder; use Lcobucci\JWT\Parser; use Lcobucci\JWT\Signer\Hmac\Sha256; use Lcobucci\JWT\ValidationData; use think\Controller; class BaseApi extends Controller { //jwt配置 private static $_config = [ "id" => "sandjsahdj8u882934784324sadjaskld19",//id号 "issuer" => "http://api.tp5.com", //签发人 授权人 "audience" => "http://www.tp5.com", //被授权人 "signer" => "asa" //盐值 ]; //获取token public static function getToken($user_id){ $signer =new Sha256(); $time = time(); $token = (new Builder())->issuedBy(self::$_config['issuer']) // Configures the issuer (iss claim) ->canOnlyBeUsedBy(self::$_config['audience']) // Configures the audience (aud claim) ->identifiedBy(self::$_config['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) ->expiresAt($time + 3600) // Configures the expiration time of the token (exp claim) ->with('uid', $user_id) // Configures a new claim, called "uid" ->sign($signer, self::$_config['signer']) // creates a signature using "testing" as key ->getToken(); // Retrieves the generated token return (string)$token; } //从token获取id public static function getUserId($token) { $user_id = null; $token = (new Parser())->parse((string) $token); //验证token $data = new ValidationData(); $data->setIssuer(self::$_config["issuer"]);//验证的签发人 $data->setAudience(self::$_config["audience"]);//验证的接收人 $data->setId(self::$_config["id"]);//验证token标识 if (!$token->validate($data)) { //token验证失败 return $user_id; } //验证签名 $signer = new Sha256(); if (!$token->verify($signer, self::$_config['signer'])) { //签名验证失败 return $user_id; } //从token中获取用户id return $token->getClaim('uid'); } }
Demo控制器:
<?php namespace app\textapi\controller; use think\App; class Demo extends BaseApi { /** * 显示资源列表 * * @return \think\Response */ public function index(){ //引用验证器 $ac = $this->validate(input(),'app\textapi\validate\Login'); if(true !== $ac){ return json($ac); } // $name = input('name'); // $prd = input('prd'); $res = db('six')->where('name',input('name'))->find(); if(input('prd') == $res['prd']){ //根据id生成jwt self::getToken($res['id']); return json(['code'=>'success','msg'=>'登录成功','data'=>null]); } else{ return json(['code'=>'failed','msg'=>'登录失败','data'=>null]); } } public function login(){ $jwt = input('token'); $data = self::getToken($jwt); if($data){ return json(['code'=>1,'msg'=>'授权成功']); }else{ return json(['code'=>0,'msg'=>'授权失败']); } } }
验证器:
<?php namespace app\textapi\validate; use think\Validate; class Login extends Validate { /** * 定义验证规则 * 格式:'字段名' => ['规则1','规则2'...] * * @var array */ protected $rule = [ 'name' => 'require', 'prd' => 'require' ]; /** * 定义错误信息 * 格式:'字段名.规则名' => '错误信息' * * @var array */ protected $message = [ 'name.require'=> "用户名必填", 'prd.require' => "密码必填", ]; }