定制 iqbalatma/laravel-jwt-authentication 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

iqbalatma/laravel-jwt-authentication

Composer 安装命令:

composer require iqbalatma/laravel-jwt-authentication

包简介

README 文档

README

This is authentication for Laravel with JWT Based. Inspired by tymondesigns/jwt-auth and PHP-Open-Source-Saver/jwt-auth. This site was built using package from firebase/php-jwt for encode and decode JWT.

How To Install

This package using syntax and feature that only available on php version at least 8.0

Install Via Composer

composer require iqbalatma/laravel-jwt-authentication

Publishing Asset

You can publish asset for customization using this command

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

Implement JWTSubject

You need to implement Iqbalatma\LaravelJwtAuthentication\Interfaces\JWTSubject on User model. If you would like to add another additional data on jwt claim, you can return array on 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 [];
    }
}

Generate JWT Credentials

This credential is used for sign jwt token and make sure the token is valid

php artisan jwt:secret

or using pairs of public and secret key

php artisan jwt:generate-certs

Configuration config/auth.php

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


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

Configuration config/jwt.php

Jwt signin using public and private key is first priority, so if you define private and public key, jwt will be signing using this key pairs. But if you do not define private and public key, jwt will use secret key for signing. If two type key does not exists, it will throw an error.

Note

Here is available algorithm if you're using secret key

  • HS512
  • HS256
  • HS384
  • HS224

Note

Here is available algorithm if you're using pairs of public and private key

  • RS512
  • RS256
  • RS384
  • ES384
  • ES256
  • ES256K
return [
    /*
    |--------------------------------------------------------------------------
    | JWT library guard
    |--------------------------------------------------------------------------
    |
    | This is guard that set in auth, because inside library guard defined manually
    | Auth::guard(config("jwt.guard"));
    |
    */
    "guard" => "jwt",


    /*
    |--------------------------------------------------------------------------
    | Access token verifier
    |--------------------------------------------------------------------------
    |
    | This is configuration to prevent xss attack by verified access token via cookie httpOnly
    |
    */
    "is_using_access_token_verifier" => true,

    /*
    |--------------------------------------------------------------------------
    | 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
    | This TTL is in seconds
    | Default 1 Hour
    |
    */
    '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
    | This TTL is in seconds
    | Default 7 Days
    */
    'refresh_token_ttl' => env('JWT_REFRESH_TTL', 60 * 60 * 24 * 7),



    /*
    |--------------------------------------------------------------------------
    | Refresh Token
    |--------------------------------------------------------------------------
    |
    | Refresh token mechanism is how middleware check/get your refresh token
    | there are two options (cookie / header)
    |
    |
    | Refresh token key is key to get when middleware mechanism choose cookie, so this key
    | is used to get cookie to set refresh token
    |
    */
    'refresh_token' => [
        'key' => 'jwt_refresh_token',
        'http_only' => true,
        'path' => "/",
        'domain' => null,
        'secure' => true,
        'same_site' => 'lax',
    ],

    /*
    |--------------------------------------------------------------------------
    | Access Token Verifier
    |--------------------------------------------------------------------------
    |
    | Access token verifier is used to prevent XSS attack by binding access token
    | to this verifier, and make sure any stolen token cannot be used by attacker
    |
    |
    */
    'access_token_verifier' => [
        'key' => 'access_token_verifier',
        'http_only' => true,
        'path' => "/",
        'domain' => null,
        'secure' => true,
        'same_site' => 'lax',
    ]
];

How to use middleware ?

When you are doing authentication, you will receive 2 types token, access and refresh. Access token use to get protected resource, for example get data product, add new data user, etc. Access token has shorter ttl, so when access token expired, you can regenerate new token with refresh token. Endpoint that do refresh token must be protected by middleware type refresh. You can see the example on how to implement this middleware bellow

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:ACCESS")->group(function () {
    Route::get("user", function () {
        return response()->json([
            "success" => true,
            "user" => Auth::user()
        ]);
    });
    
    // and others route
});

How to use ?

Here is some available method for authentication

Authenticate User

This feature used for validate credentials from user request and return back access_token and refresh_token

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, true, true);
#first parameter for credential, second parameter to tell that authentication using cookie httpOnly, third parameter to get

#if you are using access token verifier by is_using_access_token_verifier = true, its mean you need to set 
#access token in cookie httpOnly
return response()->json([
    "access_token" => "...",
])->withCookie(getCreatedCookieAccessTokenVerifier("put your access token verifier here"));

#full example
public function authenticate(AuthenticateRequest $request): JsonResponse
{
    $credentials = request(['username', 'password']);
    if (!$token = Auth::attempt($credentials)) {
        return response()->json(
            ["message" => "Invalid credentials."]
        );
    }

    /** @var User $user */
    $user = Auth::user();
    /** @var User $user */
    $user = Auth::user();
    return response()->json(
        [
            "code" => "SUCCESS",
            "message" => "Logged in successfully.",
            "timestamp" => now(),
            "payload" => [
                "data" => [
                    "id" => $user->id,
                    "username" => $user->username,
                    "first_name" => $user->first_name,
                    "last_name" => $user->last_name,
                    "email" => $user->email,
                    "access_token" => Auth::getAccessToken(),
                ],
            ],
        ]
    )
        ->withCookie(getCreatedCookieAccessTokenVerifier(Auth::getAccessTokenVerifier()))
        ->withCookie(getCreatedCookieRefreshToken(Auth::getRefreshToken()));
}

public function refresh(): JsonResponse
{
    Auth::refreshToken(Auth::user());

    /** @var User $user */
    $user = Auth::user();
    return response()->json(
        [
            "code" => "SUCCESS",
            "message" => "Logged in successfully.",
            "timestamp" => now(),
            "payload" => [
                "data" => [
                    "id" => $user->id,
                    "username" => $user->username,
                    "first_name" => $user->first_name,
                    "last_name" => $user->last_name,
                    "email" => $user->email,
                    "access_token" => Auth::getAccessToken()
                ],
            ],
        ]
    )
        ->withCookie(getCreatedCookieAccessTokenVerifier(Auth::getAccessTokenVerifier()))
        ->withCookie(getCreatedCookieRefreshToken(Auth::getRefreshToken()));
}

Logout User

This feature used for invalidate and blacklist current authorization token

use Illuminate\Support\Facades\Auth;

Auth::logout();
Auth::logout(true); #add parameter true for revoke both token pair (access and refresh)

Refresh Token

This feature used for invalidate access_token and refresh_token and invoke new access_token and refresh_token

use Illuminate\Support\Facades\Auth;

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

Login By System

This method use for login existing user via authenticable instance

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

$user = User::find(1);

Auth::login($user);

Get Token

After login or attempt method triggered and successfully, you can get token access and refresh via guard instance

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

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

$user = User::query()->where("email", "admin@mail.com")->find();
Auth::attempt($credentials); 
Auth::login($user);

Auth::getAccessToken(); #to get access token
Auth::getRefreshToken(); #to get refresh token
Auth::getAccessTokenVerifier(); #to get access token verifier

#if you are not using default guard, you need to specify the guard
Auth::guard("jwt")->getAccessToken();

iqbalatma/laravel-jwt-authentication 适用场景与选型建议

iqbalatma/laravel-jwt-authentication 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 292 次下载、GitHub Stars 达 6, 最近一次更新时间为 2023 年 10 月 30 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 iqbalatma/laravel-jwt-authentication 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 iqbalatma/laravel-jwt-authentication 我们能提供哪些服务?
定制开发 / 二次开发

基于 iqbalatma/laravel-jwt-authentication 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 292
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 6
  • 点击次数: 4
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 6
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: Unknown
  • 更新时间: 2023-10-30