generationtux/jwt-artisan

Laravel和Lumen的JWT认证包

v1.3.0 2023-03-22 17:28 UTC

README

Build Test Status

Laravel和Lumen网络工匠的Token认证

JWT是验证API请求之间各种服务的一个很好的解决方案。此包使得Laravel和Lumen都能轻松地使用JWT。

为什么选择JWT?

因为你需要

microservices

互相认证,以便可以拒绝不良请求,例如

how bout no

这就是为什么JWT让你感觉像

yea baby

内容

设置

使用composer安装包

$ composer require generationtux/jwt-artisan

为Laravel/Lumen添加适当的服务提供者

// Laravel
// config/app.php
'providers' => [
    ...
    GenTux\Jwt\Support\LaravelServiceProvider::class,
]

// Lumen
// bootstrap/app.php
$app->register(GenTux\Jwt\Support\LumenServiceProvider::class);

配置

此包的所有配置都可以使用环境变量设置。使用环境变量的原因是为了尽可能地轻松集成Laravel和Lumen。请参阅下表以了解可用的配置选项及其默认值。

如果您正在使用JwtExceptionHandler来处理异常,则可以将这些环境变量设置为自定义错误消息。(有关使用异常处理器的信息,请参见下文)

与令牌一起工作

创建令牌

GenTux\Jwt\JwtToken实例注入到您的控制器或其他服务中,以创建新令牌。

<?php

use GenTux\Jwt\JwtToken;

class TokensController extends controller
{
        public function create(JwtToken $jwt)
        {
                $payload = ["exp" => time() + 7200]; // expire in 2 hours
                $token = $jwt->createToken($payload); // new instance of JwtToken

                return (string) $token;
        }
}

实现GenTux\Jwt\JwtPayloadInterface以将其他对象传递给createToken以获得更动态的有效载荷。

<?php

use GenTux\Jwt\JwtPayloadInterface;

class User extends Model implements JwtPayloadInterface
{
        public function getPayload()
        {
                return [
                        "sub" => $this->id,
                        "exp" => time() + 7200,
                        "context" => [
                                "email" => $this->email,
                        ],
                ];
        }
}

然后在创建令牌时简单地传递该对象

<?php

use GenTux\Jwt\JwtToken;

class TokensController extends controller
{
        public function create(JwtToken $jwt)
        {
                $user = User::find(1);
                $token = $jwt->createToken($user);

                return $token->payload(); // ['sub' => 1, exp => '...', 'context' => ...]
        }
}

如果需要,您可以设置特定的secretalgorithm

public function create(JwtToken $jwt)
{
    return $jwt
            ->setSecret('secret_123')
            ->setAlgorithm('custom')
            ->createToken('[...]');
}

验证令牌

使用提供的中间件验证JWT令牌是最简单的方法。

<?php

// Laravel
Route::group(["middleware" => "jwt"], function () {
        Route::post("/foo", "FooController");
});

// Lumen
$app->group(
        ["middleware" => "jwt", "namespace" => "App\Http\Controllers"],
        function ($app) {
                $app->post("/foo", "FooController");
        }
);

如果令牌无效,将抛出GenTux\Jwt\Exceptions\InvalidTokenException异常。如果没有提供令牌,则将抛出GenTux\Jwt\Exceptions\NoTokenException异常。

要手动验证令牌,您可以使用具有GenTux\Jwt\GetsJwtToken特征的任何类获取令牌。

例如,在Laravel请求对象中

<?php

use GenTux\Jwt\GetsJwtToken;

class CreateUser extends FormRequest
{
        use GetsJwtToken;

        public function authorize()
        {
                return $this->jwtToken()->validate();
        }
}

或者在Lumen控制器中

<?php

use GenTux\Jwt\GetsJwtController;

class FooController extends controller
{
    use GetsJwtToken;

    public function store()
    {
        if( ! $this->jwtToken()->validate()) {
            return redirect('/nope');
        }

        ...
    }
}

有效载荷

一旦您有了令牌,处理有效载荷就很容易。

<?php

use GenTux\Jwt\GetsJwtToken;

class TokenService
{
        use GetsJwtToken;

        public function getExpires()
        {
                $payload = $this->jwtPayload(); // shortcut for $this->jwtToken()->payload()

                return $payload["exp"];
        }
}

JwtToken的payload方法接受一个path,可以用来从有效载荷中获取特定数据。

<?php

use GenTux\Jwt\GetsJwtToken;

class TokenService
{
        use GetsJwtToken;

        public function getData()
        {
                // ['exp' => '123', 'context' => ['foo' => 'bar']]

                $token = $this->jwtToken();
                $token->payload("exp"); // 123
                $token->payload("context.foo"); // bar
                $token->payload("context.baz"); // null
        }
}

处理错误

如果需要,此包可以自动处理JWT异常。它将处理所有JWT异常并返回JSON错误响应。如果您想实现自己的错误处理,可以查看GenTux\Jwt\Exceptions\JwtExceptionHandler作为示例。

要实现,请在app/Exceptions/Handler.php中添加以下内容

<?php

use GenTux\Jwt\Exceptions\JwtException;
use GenTux\Jwt\Exceptions\JwtExceptionHandler;

class Handler extends ExceptionHandler
{
    use JwtExceptionHandler;

    public function render($request, Exception $e)
    {
        if($e instanceof JwtException) return $this->handleJwtException($e);

        ...
    }
}