[Jwt] 在laravel中使用Jwt进行token验证

270 阅读1分钟

1. 安装扩展

composer require firebase/php-jwt

2. 创建中间件

php artisan make:middleware JwtMiddleware

3.编写中间件

<?php

namespace App\Http\Middleware;

use Closure;
use Firebase\JWT\JWT;
use Firebase\JWT\ExpiredException;
use Firebase\JWT\SignatureInvalidException;
use Illuminate\Http\Request;
use Firebase\JWT\Key;

class JwtMiddleware
{
    const JWT_SECRET = '1234567890';  // 你的秘钥

    public function handle(Request $request, Closure $next)
    {
        $token = $request->header('Authorization');
        $result = $this->_authToken($token);

        if ($result['code'] !== 0) {
            return response()->json(['message' => $result['message'], 'status' => $result['code'], 'data' => []]);
        }
        $request->merge(['uid' => $result['data']['uid']]);
        return $next($request);
    }

    private function _authToken($token)
    {
        try {
            if (!$token) {
                return [
                    'code' => 401,
                    'message' => 'Token not provided',
                    'data' => [],
                ];
            }
            $decoded = JWT::decode($token, new Key(self::JWT_SECRET, 'HS256'));
            return [
                'code' => 0,
                'message' => 'success',
                'data' => ['uid' => $decoded->sub],
            ];
        } catch (ExpiredException $e) {
            return [
                'code' => 401,
                'message' => 'Token has expired',
                'data' => [],
            ];
        } catch (SignatureInvalidException $e) {
            return [
                'code' => 401,
                'message' => 'Invalid token signature',
                'data' => [],
            ];
        } catch (\Exception $e) {
            return [
                'code' => 404,
                'message' => 'Invalid token',
                'data' => [],
            ];
        }
    }
}

4.注册中间件

app/Http/Kernel.php 文件的 $routeMiddleware 属性中注册中间件:

protected $routeMiddleware = [
    // 其他中间件...

    'jwt' => \App\Http\Middleware\JwtMiddleware::class,
];

5.改写路由

Route::post('/login', [ApiController::class, 'login']); // 

Route::middleware(['jwt'])->group(function () {
    // 在这里定义需要进行 JWT 
    Route::get('/index', [ApiController::class, 'index']);//addMachine
    Route::post('/addMachine', [ApiController::class, 'addMachine']);
    Route::get('/machineList', [ApiController::class, 'machineList']); // 
    Route::get('/machine', [ApiController::class, 'machine']); // 
    Route::get('/history', [ApiController::class, 'history']); // 
    Route::get('/apiAuthToken', [ApiController::class, 'apiAuthToken']); // 
});

6.在API控制器中使用

<?php

namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Model\Machine;
use App\Model\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Firebase\JWT\JWT; // composer require firebase/php-jwt

class ApiController extends Controller
{

    const JWT_SECRET = '1234567890';  // 你的秘钥
    const JWT_EXP_TIME = 60;         //过期时间
    const JWT_ALG = 'HS256'; // 使用的签名算法
    const JWT_ISSUER = 'your-app';

    public function index()
    {
        return response()->json([123]);
    }

    public function login(Request $request)
    {
        $username = $request->post('username');
        $password = $request->post('password');

        $userModel = new User();
        $user = $userModel->where('username', $username)->first();

        if ($user) {
            if (Hash::check($password, $user->password)) {
                 // 生成JWT令牌
                $token = $this->generateJwtToken($user);
                return $this->success(['token' => $token]);

            } else {
                return $this->error('Wrong password');
            }
        } else {
            return $this->error('User not exists');
        }
    }

    // 测试JWT
    public function apiAuthToken(Request $request)
    {
        $token = $request->header('Authorization');
        $uid = $request->uid;
        dd($uid);
    }