iqbalatma/laravel-jwt-authentication

此包最新版本(1.5.0)没有可用的许可信息。

1.5.0 2024-08-01 08:59 UTC

README

这是基于JWT的Laravel认证。受tymondesigns/jwt-authPHP-Open-Source-Saver/jwt-auth的启发。本网站使用来自firebase/php-jwt的包进行JWT的编码和解码。

下一个功能

以下是下一个功能的列表

  • 在编码和解码JWT时使用证书
  • 创建用于生成证书的命令行工具
  • 在守卫登录时设置用户
  • 在守卫登出时重置用户
  • 在config/jwt.php中添加信息
  • 将配置从jwt_iqbal重命名为jwt
  • 将守卫从jwt-iqbal重命名为jwt
  • [] 实现测试
  • [] 实现多黑名单驱动程序

如何安装

此包使用仅在PHP版本至少为8.0上可用的语法和功能。

composer require iqbalatma/laravel-jwt-authentication

发布资产

您可以使用以下命令发布资产进行自定义

php artisan vendor:publish --provider='Iqbalatma\LaravelJwtAuthentication\LaravelJWTAuthenticationProvider'

生成JWT凭证

此凭证用于签名JWT令牌并确保令牌有效

php artisan jwt:secret

或使用公钥和私钥对

php artisan jwt:generate-certs

配置 config/auth.php

'defaults' => [
    'guard' => 'jwt',
    'passwords' => 'users',
],


'guards' => [
    ...
    "jwt" => [
        "driver" => "jwt",
        "provider" => "users"
    ]
],

配置 config/jwt.php

JWT登录使用公钥和私钥为首要选择,因此如果您定义了私钥和公钥,JWT将使用此密钥对进行签名。但是,如果您未定义私钥和公钥,JWT将使用密钥进行签名。如果两种类型的密钥都不存在,则将引发错误。

注意

以下是使用密钥时可用算法

  • HS512
  • HS256
  • HS384
  • HS224

注意

以下是使用公钥和私钥对时可用算法

  • RS512
  • RS256
  • RS384
  • ES384
  • ES256
  • ES256K
<?php
  /*
    |--------------------------------------------------------------------------
    | JWT Sign in Algorithm
    |--------------------------------------------------------------------------
    |
    | Algorithm for sign jwt token. This token is using encoder and decoder from
    | https://github.com/firebase/php-jwt
    |
    */
    'algo' => env('JWT_ALGO', 'HS256'),


    /*
    |--------------------------------------------------------------------------
    | JWT Private Key
    |--------------------------------------------------------------------------
    |
    | This private key use for first priority of encoding and decoding jwt (signing)
    | so if this key (private key) and (public key) exists, jwt will sign using
    | this key pairs as first priority. If this key pairs does not exist, sign jwt will
    | using jwt secret. If secret does not exist it will throw an error
    |
    */
    "jwt_private_key" => env("JWT_PRIVATE_KEY", null),

    /*
    |--------------------------------------------------------------------------
    | JWT Public Key
    |--------------------------------------------------------------------------
    |
    | This public key is part of key pairs for signing jwt token.
    |
    */
    "jwt_public_key" => env("JWT_PUBLIC_KEY", null),


    /*
    |--------------------------------------------------------------------------
    | JWT Passphrase
    |--------------------------------------------------------------------------
    |
    | This is passphrase use to get jwt private key that translate the key
    | using this passphrase
    |
    */
    "jwt_passphrase" => env("JWT_PASSPHRASE", null),

    /*
    |--------------------------------------------------------------------------
    | Secret
    |--------------------------------------------------------------------------
    |
    | This is secret that used for encoding jwt. This secret use to validate signature
    | Do not expose this jwt secret
    |
    */
    'secret' => env('JWT_SECRET', null),


    /*
    |--------------------------------------------------------------------------
    | Access Token TTL
    |--------------------------------------------------------------------------
    |
    | This is TTL (Time To Life) for access token. When token is expired, the token
    | is already invalid. Access token using to access protected resource.
    | Middleware that can accept this token is auth.jwt:access
    |
    */
    'access_token_ttl' => env('JWT_TTL', 60 * 60),


    /*
    |--------------------------------------------------------------------------
    | Refresh Token TTL
    |--------------------------------------------------------------------------
    |
    | This is TTL (Time To Life) for refresh token. When token is expired, the token
    | is already invalid. Refresh token using to regenerate access token and refresh token
    | and revoke previous access token and refresh token.
    | Middleware that can accept this token is auth.jwt:refresh
    |
    */
    'refresh_token_ttl' => env('JWT_REFRESH_TTL', 60 * 60 * 24 * 7),

实现JWTSubject

您需要在User模型上实现Iqbalatma\LaravelJwtAuthentication\Interfaces\JWTSubject。如果您想在JWT声明中添加其他附加数据,您可以在getJWTCustomClaims中返回数组。

use Iqbalatma\LaravelJwtAuthentication\Interfaces\JWTSubject;
class User extends Authenticatable implements JWTSubject
{
    public function getJWTIdentifier(): string|int
    {
        return $this->getKey();
    }

    public function getJWTCustomClaims(): array
    {
        return [];
    }
}

如何使用中间件?

当您进行身份验证时,您将收到两种类型的令牌,访问和刷新。访问令牌用于获取受保护资源,例如获取产品数据、添加新用户数据等。访问令牌的TTL较短,因此当访问令牌过期时,您可以使用刷新令牌重新生成新令牌。执行刷新令牌的端点必须由类型为刷新的中间件进行保护。您可以在下面的示例中看到如何实现此中间件

use Illuminate\Support\Facades\Route;

//jwt middleware that need refresh token
Route::post("refresh-token", function (){
    //do refresh logic here
})->middleware("auth.jwt:refresh");


//jwt middleware that need access token
Route::middleware("auth.jwt")->group(function () {
    Route::get("user", function () {
        return response()->json([
            "success" => true,
            "user" => Auth::user()
        ]);
    });
    
    // and others route
});

如何使用?

这里有一些可用的身份验证方法

验证用户

此功能用于验证用户请求中的凭据并返回访问令牌和刷新令牌

use Illuminate\Support\Facades\Auth;

$credentials = [
    "email" => "admin@mail.com",
    "password" => "admin"
];

#this attempt method will return boolean when user validation success
Auth::attempt($credentials);

#passing true on second parameter to get return array of access_token and refresh_token
Auth::attempt($credentials, true);

用户登出

此功能用于使当前授权令牌失效并加入黑名单

use Illuminate\Support\Facades\Auth;

Auth::logout();

刷新令牌

此功能用于使访问令牌和刷新令牌失效并调用新的访问令牌和刷新令牌

use Illuminate\Support\Facades\Auth;

Auth::refreshToken(Auth::user());

系统登录

此方法用于通过认证实例登录现有用户

use Illuminate\Support\Facades\Auth;
use App\Models\User;

$user = User::find(1);

Auth::login($user);

获取令牌

在登录或尝试方法被触发并成功后,您可以通过守卫实例获取访问令牌和刷新令牌

use Illuminate\Support\Facades\Auth;
use App\Models\User;

$credentials = [
    "email" => "admin@mail.com",
    "password" => "admin"
];

Auth::attempt($credentials);

Auth::getAccessToken();
Auth::getRefreshToken();

已发行令牌服务

这是一个与已发行令牌、访问或刷新令牌相关的服务。您可以通过用户代理获取已发行令牌的列表或撤销令牌

use Iqbalatma\LaravelJwtAuthentication\Services\IssuedTokenService;

#use to get all issued token
IssuedTokenService::getAllToken();

#use to get all issued refresh token
IssuedTokenService::getAllTokenRefresh()

#use to get all issued access token
IssuedTokenService::getAllTokenAccess();

#use to revoke refresh token by user agent string name
IssuedTokenService::revokeTokenRefreshByUserAgent('user-agent-name');

#use to revoke access token by user agent string name
IssuedTokenService::revokeTokenAccessByUserAgent('user-agent-name');

#use to revoke both access and refresh token by user agent string name
IssuedTokenService::revokeTokenByUserAgent('user-agent-name');

#use to revoke all token
IssuedTokenService::revokeAllToken();

#use to revoke all token but current token
IssuedTokenService::revokeAllTokenOnOtherUserAgent();