tp6+jwt+vue验证token

12 篇文章 3 订阅
  1. 使用compose安装jwt类,compose没安装的自行百度

(在cmd中切换至tp项目文件夹中运行一下命令,运行成功后会在vendor目录中生成firebase)

composer require firebase/php-jwt

2.在app/common.php引入JWT类,创建生成token、验证token方法

<?php
// 应用公共文件
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Firebase\JWT\SignatureInvalidException;
use Firebase\JWT\ExpiredException;
use Firebase\JWT\BeforeValidException;

/**
 * 生成token
 * $uid 输入用户openid&&id
 */

if (!function_exists('signToken')) {
    //生成验签
    function signToken($uid,$key)//这里$key参数应该写在config文件中的,偷懒了..
    {
        $token = array(
            "iss" => '',             //签发者 可以为空
            "aud" => '',             //面象的用户,可以为空
            "iat" => time(),          //签发时间
            "nbf" => time() + 3,          //在什么时候jwt开始生效  (这里表示生成100秒后才生效)
            "exp" => time() + 2000, //token 过期时间
            'data' => $uid            //记录的userid的信息,这里是自已添加上去的,如果有其它信息,可以再添加数组的键值对
        );
        //根据参数生成了 token
        return JWT::encode($token, $key, "HS256");
    }
}
/**
 * 验证token
 * $token 生成的token值
 */

if (!function_exists('checkToken')) {
    //验证token
    function checkToken($token,$key)//这里$key参数应该写在config文件中的,偷懒了..
    {
        $status = array("code" => 2);

        try {
            JWT::$leeway = 60; //当前时间减去60,把时间留点余地
            $decoded = JWT::decode($token, new Key($key, 'HS256')); //HS256方式,这里要和签发的时候对应
            $arr = (array)$decoded;
            $res['code'] = 200;
            $res['data'] = $arr['data'];
            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;
        }
    }
}

3.创建中间件,建议用命令,手动创建也可以的

(在cmd中切换至tp项目文件夹中运行命令,会自动创建app/middleware/Check.php文件)

php think make:middleware Check

(Check.php中间件的内容直接复制粘贴,包含了处理跨越请求)

<?php
declare (strict_types = 1);

namespace app\middleware;

use Closure;
use think\Request;
use think\Response;

class Check
{
    public function handle($request, Closure $next, ?array $header = [])
    {
        try {
            if (empty($request->header('Token')) || $request->header('Token') == '')
                throw new Exception('Without Token',201);
            $request->res = checkToken( $request->header('Token'),'!@v-/we#H-^TQ$%1589*0842&'); // 验证token
            if($request->res['code'] == 200){
                return $next($request);
            }else{
                return $next($request->res['msg']);
            }
        }catch (Exception $err){
            return json(['code'=>$err->getCode(),'msg'=>$err->getMessage()]);
        }
    }
}

4.控制器(有些代码注释,因为本人用的vue-element-admin后台模板,要整理对应的数据类型

 /**
     * 登入后台获取token
     */
public function login(Request $request)
    {
        $data = $request->param();
        //if ($data['type'] == 'manager'){
            //使用验证器
            //$this ->validate($data,Articlevalidate::class);

            $user = Admin_user::Where('user_name',$data['username'])->find();
            if (!empty($user) && md5($data['password']) == $user['password']){
                //$user['roles'] = explode(",", $user['roles']);
                $token = signToken($user,'!@TQ$%1a8*092&');//这里第二个参数应该写在config文件中的,偷懒了..

                //$personal_object = new stdClass();
                //$personal_object->token = $token;
                //return json(['code'=>200,'data' => $personal_object,'message'=>'登入成功']);
                return json(['code'=>200,'data' => $token,'message'=>'登入成功']);
            }else{
                return json(['code'=>201,'message'=>'用户名或密码错误']);
            }
        //}else{
            //return '非法请求';
        //}
    }

/**
     * 获取用户信息,模拟登入后
     */
    public function info(Request $request)
    {
        $user = $request->res;
        return json(['code'=>200,'data' => $user,'message'=>'获取成功']);
    }

5.大坑,vue项目一定要处理跨域,不然游览器永远拦截,这里我做了跨域

//登入
Route::group('admin',function () {
    Route::post('user/login','app\controller\Admin\Admin_Index_Login@login');//(登入)
})->allowCrossDomain([
    'Access-Control-Allow-Origin'        => '*',
    'Access-Control-Allow-Headers'       =>'Origin, Content-Type, Cookie, X-CSRF-TOKEN, Accept, Authorization, X-XSRF-TOKEN',
    'Access-Control-Allow-Methods'       =>'GET, POST, PUT, DELETE',
    'Access-Control-Allow-Credentials'   => 'true'
]);

//登入后
Route::group('admin',function () {
    Route::get('user/info','app\controller\Admin\Admin_Index_Login@info');//(获取用户信息)
})->allowCrossDomain([
    'Access-Control-Allow-Origin'        => '*',
     //Access-Control-Allow-Headers这里加上自己定义的Headers头,我的是Token,刚刚的中间件Check.php,
    'Access-Control-Allow-Headers'       =>'Origin, Content-Type, Cookie, X-CSRF-TOKEN, Accept, Authorization, X-XSRF-TOKEN,Token',
    'Access-Control-Allow-Methods'       =>'GET, POST, PUT, DELETE',
    'Access-Control-Allow-Credentials'   => 'true'
])->middleware(\app\middleware\Check::class);//中间件的文件路径;

如果是全局中间件,不是就不用理,在app/middleware.php新加以下内容,Session可以不开不影响

<?php
// 全局中间件定义文件
return [
    // 全局请求缓存
    // \think\middleware\CheckRequestCache::class,
    // 多语言加载
    // \think\middleware\LoadLangPack::class,
    // Session初始化
    \think\middleware\SessionInit::class,
    //跨中间件
    // \think\middleware\AllowCrossDomain::class,
    \app\middleware\AllowCrossDomain::class
];

6.vue+axios发送请求时设置header信息

// get
axios.get(url, {headers:{Token: '***Token的值****'}})

// post
axios.post(url, data, {headers:{Token: '***Token的值*****'}})
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值