login每天学习一点点,每天进步一点点.
当前位置:首页 >> JWT

JWT

2018-11-27 14:18:44  |  分类: Php |  标签: 阅读(60)评论(0)

1、获取token   控制器Index.php

<?php
namespace app\index\controller;

use think\Controller;
use app\extra\Jwt;

class Index extends BaseController
{
    // protected $jwt;
	public function __construct()
    {
        // $this->jwt = new jwt;
        // parent::__construct();
    }

    public function index()
    {
        return '1';
    }

    public function login(){
    	echo "login Success";
    	$this->getToken();
    	//客户端登陆成功后,储存token,带token请求
    }

    public function gettoken(){
    	// $jwt = new jwt;
		$payload_test=array('iss'=>'admin','iat'=>time(),'exp'=>time()+7200,'nbf'=>time(),'sub'=>'www.19aq.com','jti'=>md5(uniqid('JWT').time()));;
		$token_test=jwt::getToken($payload_test);
		dump($token_test);
    }

}

效验token  继承类 BaseController.php  

<?php
namespace app\index\controller;

use think\Controller;
use app\extra\Jwt;

//权限管控模块
class BaseController extends Controller
{
    public function __construct()
    {
        $this->login_check();
        header("Content-type:application/Json");
        //调用父类构造方法
        parent::__construct();
    }

    public function login_check(){
    	$jwt = new jwt;
    	if (isset($_SERVER['HTTP_TOKEN'])) {
    		$token = $_SERVER['HTTP_TOKEN'];
    		$res = jwt::verifyToken($token);
    		if (!$res) {echo json_encode(array('code'=>2600,'msg'=>'token invalid.','data'=>""));die;}
    		dump($res);
    	}else{
    		echo json_encode(array('code'=>2600,'msg'=>'Please login.','data'=>""));die;
    	}
    }
}

第三方类   文件名 Jwt.php

<?php
namespace app\extra;

final class Jwt
{
	// // 请求头加  TOKEN

	// //测试和官网是否匹配begin
	// $payload=array('sub'=>'1234567890','name'=>'John Doe','iat'=>1516239022);
	// // $jwt=new Jwt;
	// $jwt= $this;
	// $token=$jwt->getToken($payload);
	// echo "<pre>";
	// echo $token;

	// // //对token进行验证签名
	// $getPayload=$jwt->verifyToken($token);
	// echo "<br><br>";
	// var_dump($getPayload);
	// echo "<br><br>";
	// // //测试和官网是否匹配end

	// // //自己使用测试begin    iss签发者 sub面向用户 iat签发时间 exp过期时间 nfb定义什么时间前不可用 jti唯一身份标识
	// $payload_test=array('iss'=>'admin','iat'=>time(),'exp'=>time()+7200,'nbf'=>time(),'sub'=>'www.19aq.com','jti'=>md5(uniqid('JWT').time()));;
	// $token_test=$jwt->getToken($payload_test);
	// echo "<pre>";
	// echo $token_test;

	// // //对token进行验证签名
	// $getPayload_test=$jwt->verifyToken($token_test);
	// echo "<br><br>";
	// var_dump($getPayload_test);
	// echo "<br><br>";
	// // //自己使用时候end


	//头部
    private static $header=array(
		'alg'=>'HS256', //生成signature的算法
		'typ'=>'JWT'  //类型
	);

	//使用HMAC生成信息摘要时所使用的密钥
	private static $key='123456';

	/**
	* 获取jwt token
	* @param array $payload jwt载荷  格式如下非必须
	* [
	* 'iss'=>'jwt_admin', //该JWT的签发者
	* 'iat'=>time(), //签发时间
	* 'exp'=>time()+7200, //过期时间
	* 'nbf'=>time()+60, //该时间之前不接收处理该Token
	* 'sub'=>'www.admin.com', //面向的用户
	* 'jti'=>md5(uniqid('JWT').time()) //该Token唯一标识
	* ]
	* @return bool|string
	*/
    public static function getToken(array $payload){
		if(is_array($payload)){
			$base64header=self::base64UrlEncode(json_encode(self::$header,JSON_UNESCAPED_UNICODE));
			$base64payload=self::base64UrlEncode(json_encode($payload,JSON_UNESCAPED_UNICODE));
			$token=$base64header.'.'.$base64payload.'.'.self::signature($base64header.'.'.$base64payload,self::$key,self::$header['alg']);
			return $token;
		}else{
			return false;
		}
	}

	/**
	* 验证token是否有效,默认验证exp,nbf,iat时间
	* @param string $Token 需要验证的token
	* @return bool|string
	*/
	public static function verifyToken(string $Token){
		$tokens = explode('.', $Token);
		if (count($tokens) != 3)
			return false;

		list($base64header, $base64payload, $sign) = $tokens;

		//获取jwt算法
		$base64decodeheader = json_decode(self::base64UrlDecode($base64header), JSON_OBJECT_AS_ARRAY);
		if (empty($base64decodeheader['alg']))
			return false;

		//签名验证
		if (self::signature($base64header . '.' . $base64payload, self::$key, $base64decodeheader['alg']) !== $sign)
			return false;

		$payload = json_decode(self::base64UrlDecode($base64payload), JSON_OBJECT_AS_ARRAY);

		//签发时间大于当前服务器时间验证失败
		if (isset($payload['iat']) && $payload['iat'] > time())
			return false;

		//过期时间小宇当前服务器时间验证失败
		if (isset($payload['exp']) && $payload['exp'] < time())
			return false;

		//该nbf时间之前不接收处理该Token
		if (isset($payload['nbf']) && $payload['nbf'] > time())
			return false;

		return $payload;
	}

	/**
	* base64UrlEncode  https://jwt.io/ 中base64UrlEncode编码实现
	* @param string $input 需要编码的字符串
	* @return string
	*/
	private static function base64UrlEncode(string $input){
		return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));
	}

	/**
	* base64UrlEncode https://jwt.io/ 中base64UrlEncode解码实现
	* @param string $input 需要解码的字符串
	* @return bool|string
	*/
	private static function base64UrlDecode(string $input){
		$remainder = strlen($input) % 4;
		if ($remainder) {
			$addlen = 4 - $remainder;
			$input .= str_repeat('=', $addlen);
		}
		return base64_decode(strtr($input, '-_', '+/'));
	}

	/**
	* HMACSHA256签名  https://jwt.io/ 中HMACSHA256签名实现
	* @param string $input 为base64UrlEncode(header).".".base64UrlEncode(payload)
	* @param string $key
	* @param string $alg  算法方式
	* @return mixed
	*/
	private static function signature(string $input, string $key, string $alg = 'HS256'){
		$alg_config=array(
			'HS256'=>'sha256'
		);
		return self::base64UrlEncode(hash_hmac($alg_config[$alg], $input, $key,true));
	}
}


上一篇:ubuntu使用nmap查询端口 下一篇:ThinkPHP5 的视图$view->fetch()和$view->display()的区别

猜你喜欢

发表评论:

0.031514s