thinkphp6 jwt

文章描述:

token一般是用户在输入账号密码登录后生成的再次请求验证秘钥

token优势

支持跨域访问:cookie是无法跨域的,而token由于没有用到cookie(前提是将token放到请求头中),所以跨域后不会存在信息丢失问题

无状态:token机制在服务端不需要存储session信息,因为token自身包含了所有登录用户的信息,所以可以减轻服务端压力

 

安装

Thinkphp6

在WEB根目录下面并执行下面的命令

composer create-project topthink/think tp6

 

多应用

composer require topthink/think-multi-app

 

JWT扩展

composer require firebase/php-jwt

 

应用

建后台应用

php think build admin

建立前台应用

php think build api 

 

在应用控制器下面新建公用Controller.php

<?php
declare (strict_types = 1);
 
namespace app\admin\controller;
use app\BaseController;
use think\response\Json;
 
class Controller extends BaseController
{
 
    /**
     * 初始化
     */
    public function initialize()
    {
        //拦截验证
        //do something
    }
 
 
    /**
     * 返回封装后的 API 数据到客户端
     */
    protected function renderData(int $status = null, string $message = '', array $data = []): Json
    {
        is_null($status) && $status = config('status.success');
        return json(compact('status', 'message', 'data'));
    }
 
    /**
     * 返回操作成功json
     * @param array|string $data
     * @param string $message
     * @return Json
     */
    protected function renderSuccess($data = [], string $message = 'success'): Json
    {
        if (is_string($data)) {
            $message = $data;
            $data = [];
        }
        return $this->renderData(200, $message, $data);
    }
 
    /**
     * 返回操作失败json
     * @param string $message
     * @param array $data
     * @return Json
     */
    protected function renderError(string $message = 'error', array $data = []): Json
    {
        return $this->renderData(500, $message, $data);
    }
 
    /**
     * 获取post数据 (数组)
     * @param $key
     * @return mixed
     */
    protected function postData($key = null)
    {
        return $this->request->post(empty($key) ? '' : "{$key}/a");
    }
 
    /**
     * 获取post数据 (数组)
     * @param string $key
     * @return mixed
     */
    protected function postForm(string $key = 'form')
    {
        return $this->postData($key);
    }
 
    /**
     * 获取post数据 (数组)
     * @param $key
     * @return mixed
     */
    protected function getData($key = null)
    {
        return $this->request->get(is_null($key) ? '' : $key);
    }
}

 

然后再加上 jwt 的公用方法,在commen.php里面写

<?php
// 应用公共文件
use Firebase\JWT\BeforeValidException;
use Firebase\JWT\ExpiredException;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Firebase\JWT\SignatureInvalidException;
 
const JWT_TTL = 7200;
/**生成验签
 * @param $data
 * @return string
 */
function signToken($data) :string
{
    $key='LAL@lc!';         //这里是自定义的一个随机字串,应该写在config文件中的,解密时也会用,相当于加密中常用的 盐-salt
    $token=array(
        "iss" => $key,        //签发者 可以为空
        "aud" => '',          //面象的用户,可以为空
        "iat" => time(),      //签发时间
        "nbf" => time() + 3,    //在什么时候jwt开始生效  (这里表示生成100秒后才生效)
        "exp"=> time() + JWT_TTL, //token 过期时间
        "data"=> $data           //记录的userid的信息,这里是自已添加上去的,如果有其它信息,可以再添加数组的键值对
    );
    return JWT::encode($token, $key, "HS384");  //根据参数生成了token,可选:HS256、HS384、HS512、RS256、ES256等
}
 
/**验证token
 * @param $token
 * @return array|int[]
 */
function checkToken($token) :array
{
    $key = 'LAL@lc!';
    $status = ['code' => 500];
    try {
        JWT::$leeway = 60;//当前时间减去60,把时间留点余地
        $decoded = JWT::decode($token, new Key($key, 'HS384')); //同上的方式,这里要和签发的时候对应
        $arr = (array)$decoded;
        $res['code'] = 200;
        $res['data'] = $arr['data'];
        $res['data'] = json_decode(json_encode($res['data']), true);//将stdObj类型转换为array
        return $res;
 
    } catch (SignatureInvalidException $e) { //签名不正确
        $status['msg'] = "签名不正确";
        return $status;
    } catch (BeforeValidException $e) { // 签名在某个时间点之后才能用
        $status['msg'] = "token失效";
        return $status;
    } catch (ExpiredException $e) { // token过期
        $status['msg'] = "token失效";
        return $status;
    } catch (Exception $e) { //其他错误
        $status['msg'] = "未知错误";
        return $status;
    }
}

 

在admin应用的controller/Index

<?php
declare (strict_types = 1);

namespace app\admin\controller;

use think\response\Json;

class Index extends Controller
{
    public function index():Json
    {
        $data = [
            'id' => 1,
            'info' => array('username' => '小坏蛋','age'=>22,'email'=>'123456@qq.com')
        ];
        $data['token'] = signToken($data);
        return $this->renderSuccess($data);
    }
    public function check():Json
    {
        $token = $this->request->header('token');
        $user_info = checkToken($token);
        if($user_info['code'] != 200){
            return $this->renderError('token验证失败');
        }
        return $this->renderSuccess($user_info,'验证成功');
    }
}

 

发布时间:2023/11/16

发表评论