Json Web Token是在开发APP API中经常用到的权限验证方式

有时候我们需要对jwt进行验证,而如果只是API开发者不是APP的开发者,只能使用js代码进行验证。

一、需求

需要开发一套API供APP与前端代码使用,使用jquery进行API的token的测试。

一篇比较好的jwt的介绍:

二、前提

PHP JWT库使用的是lcobucci/jwt,github地址:

这个库用起来非常的简单,缺点是没有Autoloader.php,作为一个composer包没有的话,在非框架的php代码中存在各种异常。

三、实现

使用JWT的验证的话,首先用户需要登录,后台验证成功后生成用户的token,然后返回给用户,之后但凡涉及用户的操作,如修改信息,都必须携带token。

而客户端发送token的时候,token是放在header中Authorization

1、获得token

ajax发送请求,获得token:

 function getToken(){
        var url=$("#url").val(),
            name=$("#name").val(),
            password=$("#password").val();
        $.ajax({
            'url':url,
            'dataType':'json',
            'type':'post',
            'data':'name='+name+"&password="+password,
            success:function(data){
                if(data.code==0){
                    $("#tokenWell").html(data.data['token']);
                }else{
                    alert(data.msg);
                }
            }
        });
    }

php代码使用lcobucci/jwt生成token并返回:

/**
 * You should import class or interface of Lcobucci\JWT
 */

use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Signer\Hmac\Sha256;

// Select the encryption method
    $signer= new Sha256();
// create the encryption key
    $signerKey='testsignature';
// get $name & $password
// demo name = postbird ; password = 123456
$name=trim($_POST['name']);
$password=trim($_POST['password']);
// check user with demo;
if($name!='postbird' || $password!='123456'){
    $resData=[
        'code'=>1,
        'status'=>'error',
        'msg'=>'Error username or password'
    ];
    // return the info .encode by json.
    echo json_encode($resData);
    return;
}
// If user's info is true.Create the token.
// composer require Lcobucci\JWT
// github:https://github.com/lcobucci/jwt/blob/3.2/README.md
$token=(new Builder())
    ->setIssuer('http://testjwt.ptbird.cn')
    ->setAudience('http://testjwt.ptbird.cn')
    ->setId($name,true) //
    ->setIssuedAt(time()) //
    ->setExpiration(time()+3600)//
    ->set('username',$name)//
    ->sign($signer,$signerKey) //
    ->getToken();
$token->getHeaders();
$token->getClaims();
$resData=[
    'code'=>0,
    'status'=>'ok',
    'msg'=>'Get Token Success.',
    'data'=>['token'=>(string)$token]
];
// return the info .encode by json.
echo json_encode($resData);
return;

2、验证token

ajax发送请求,验证token,其中token存放在header Authorization

function verifyToken(){
        var url=$("#actionUrl").val(),
            token=$("#token").val(),
            message=$("#testMessage").val(),
            username=$("#tokenUsername").val();
        $.ajax({
            'url':url,
            'dataType':'json',
            'type':'post',
            'beforeSend':function(request) {
                request.setRequestHeader("Authorization", token);
            },
            'data':'message='+message+"&name="+username,
            success:function(data){
                if(data.code==0){
                    $("#checkMessageWell").html(data.data['message']);
                }else{
                    alert(data.msg);
                }
            }
        });
    }

php验证token

use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\ValidationData;

/**
    echo "<pre>";
    print_r(apache_request_headers());
    echo "</pre>";
*/

// get message
$message=trim($_POST['message']);
$name=trim($_POST['name']);
// get token from http header 'Authorization'

$tokenStr=apache_request_headers()['Authorization'];
$signer= new Sha256();
$signerKey='testsignature';

try{
    $token=(new Parser())->parse((string)$tokenStr);
    $token->getHeaders();
    $token->getClaims();
    if(!$token->verify($signer,$signerKey)){
        $resData=[
            'code'=>1,
            'status'=>'fail',
            'msg'=>'signature false',
        ];
        return json()->data($resData);
    }
    $validata=new ValidationData();
    $validata->setIssuer('http://tp5.ptbird-ubuntu');
    $validata->setAudience('http://tp5.ptbird-ubuntu');
    $validata->setId($name);
    if(!$token->validate($validata)){
        $resData=[
            'code'=>1,
            'status'=>'fail',
            'msg'=>'validation fail',
        ];
       echo json_encode($resData);
       return ;
    }
    $username=$token->getClaim('username');
    if($username!=$name){
        $resData=[
            'code'=>1,
            'status'=>'fail',
            'msg'=>'name is not the same to username in token',
        ];
        echo json_encode($resData);
        return ;
    }
    // true token
    $resData=[
        'code'=>0,
        'status'=>'ok',
        'msg'=>'token verify true.',
        'data'=>['message'=>'Hello '.$name.' and your token is true.']
    ];
    echo json_encode($resData);
    return ;
}catch (\Exception $e){
    $resData=[
        'code'=>1,
        'status'=>'fail',
        'msg'=>$e->getMessage(),
    ];
    echo json_encode($resData);
    return ;
}

1.jpg