ThinkPHP5-使用 think-API 部署 JWT

因为下一个项目要用TP5开发一个小程序,所以就使用到了,TP框架,因为小程序开发需要后台来编写api接口,所以就上网查了一下有没有相关的依赖,在此推荐一下think-api扩展工具,因为主要想使用其中的jwt功能来判断小程序用户的登录状态,下面就以本人的项目为例,简单和大家聊一下,通过think-api来部署JWT。

1.安装依赖

本人使用的 TP 版本是 TP5.1,扩展下载地址:https://github.com/czewail/think-api ,通过composer安装依赖:

$ composer require zewail/think-api:1.1.x

2.配置说明

扩展安装完毕后,咱们可以在 vendor/think-api/config/jwt.php文件中查看 jwt 的配置。

主要是用户模型路径那块,需要修改一下:

return [
    // 加密算法
    'algorithm'      => 'HS256',
    // HMAC算法使用的加密字符串
    'key'            => 'ex-key',
    // RSA算法使用的私钥文件路径
    'privateKeyPath' => '/home/rsa_private_key.pem',
    // RSA算法使用的公钥文件路径
    'publicKeyPath'  => '/home/rsa_public_key.pem',
    // 误差时间,单位秒
    'deviation'      => 60,
    // 过期时间, 单位分钟
    'ttl'            => 120,
    // 用户模型路径
    'user'           => app\api\model\User::class,
];

3.创建API接口控制器

通过命令行创建我们想要反回Token给前端的控制器

$ php think make:controller api/Index

4.引用依赖

在创建的文件头添加文件路径:use Zewail\Api\Facades\JWT;案例代码如下:

    public function index()
    {
        //获取前台发送过来的登录信息
        $tel      = $this->request->tel;
        $password = $this->request->passwword;
        //把登录信息传入JWT验证匹配
        $credentials = ['tel' => $tel, 'password' => $password];
        //1.验证通过返回token  1和2任意取一种方式
        $token = JWT::attempt($credentials);
        //2.通过已有账户模型生成token  1和2任意取一种方式
        $user  = User::find(84);
        $token = JWT::fromUser($user);
        $msg   = "验证成功";
        //把token发送给前台确认是否成功登陆
        return $this->ApiSuccess($token, $msg);
    }

有一点需要注意因为API离默认的接收参数是 mobile 和 password 。上门的例子中是 tel 和 password 。更改了变量名称,所以我们需要在用户模型中接入一下代码来说明。以此类推。
public $jwtSub = 'tel';

5.配置路由

route/route.php中加入路由地址 Route::get('api/test', 'api/Index/index');

6.运行测试

在 postman 中测试结果如下,这样咱们就可以在后台生成 token 返给前台验证登录了。

ThinkPhp5-使用think-api部署JWT

7.验证token(补充)

我们在 postman 中把之前生成的 token 已头部的方式重新发送到后台,来进行 token 验证,以下图为例。

ThinkPHP5-使用 think-API 部署 JWT

之后携带头部访问验证路由,验证代码如下:

       if ($user = JWT::authenticate()) {
                return true;
        } 

如果验证无误就会返回true。

8.关于token不存在及token过期的问题处理(补充)

vendor\think-api\src\JWT/Factories\code.php文件中 think-api 接口为咱们提供了对应的错误反馈。

// 检查是否过期
if (isset($payload->exp) && (time() - $this->deviation) >= $payload->exp) {
    throw new TokenExpiredException('该 Token 已过期');
}
// 验证签名
if (!$this->verify("$header64.$payload64", $signature)) {
    throw new TokenInvalidException('无效的 Token');
}

那么咱们如何利用这些状态反馈呢,这就要使用前置中间件的方式来对前端发送的 token 信息进行验证。

首先创建中间件:

$ php think make:middle Test 

然后在中间件中写入以下内容:

    //用try catch捕获报错反馈
    public function handle($request, Closure $next)
    {
        try {
            if (!$user = JWT::authenticate()) {
                return response()->json([
                    'errcode' => 1004,
                    'errmsg'  => '无此用户',

                ], 404);
            }
            return $next($request);

        } catch (TokenExpiredException $e) {

            return response()->json([
                'errcode' => 1003,
                'errmsg'  => 'token 过期', //token已过期
            ]);

        } catch (TokenInvalidException $e) {

            return response()->json([
                'errcode' => 1002,
                'errmsg'  => 'token 无效', //token无效
            ]);

        } catch (JWTException $e) {

            return response()->json([
                'errcode' => 1001,
                'errmsg'  => '缺少token', //token为空
            ]);

        }
    }

之后再在路由上门引用就可以了。

本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 4年前 自动加精
lanffff
讨论数量: 11

过期怎么处理

4年前 评论
lanffff (楼主) 4年前

不错,最近项目需要JWT,试一下

4年前 评论

为什么 3 4 5 6 解析成代码了

4年前 评论
lanffff (楼主) 4年前
lmaster

加油哦

4年前 评论
lanffff (楼主) 4年前

5.0版本的tp不能用吗?

4年前 评论
lanffff (楼主) 4年前

可以多个用户模型吗

4年前 评论
快乐壮

6.0现在支持吗?

4年前 评论

我还说写个jwt,发现这里有,jwt黑名单怎么处理的?

4年前 评论
gaorenhua

我按照你的代码写的,改了token,捕获不到异常咋回事。

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!