agungsugiarto/codeigniter4-authentication-jwt

为 codeigniter4 身份验证提供 JSON Web Token。

v1.0.0-beta.2 2022-05-11 06:13 UTC

This package is auto-updated.

Last update: 2024-09-11 11:08:42 UTC


README

Latest Stable Version Total Downloads Latest Unstable Version License

关于

为 codeigniter4-authentication 提供的 JSON Web Token。此包是从 tymondesigns/jwt-auth 端口迁移的,以兼容 agungsugiarto/codeigniter4-authentication

文档

通过 Composer 安装

composer require agungsugiarto/codeigniter4-authentication-jwt

复制配置

将配置文件从 vendor/agungsugiarto/codeigniter4-authentication-jwt/src/Config/JWT.php 复制到您的 codeigniter4 应用程序的配置文件夹,并将类扩展从 BaseConfig 更改为 \Fluent\JWTAuth\Config\JWT

更新您的用户实体

首先,您需要在您的用户实体上实现 Fluent\JWTAuth\Contracts\JWTSubjectInterface 接口,这需要您实现 2 个方法 getJWTIdentifier()getJWTCustomClaims()

下面的示例应为您提供一些思路。显然,您应该根据您的需求进行任何必要的更改。

namespace App\Entities;

//..
use Fluent\JWTAuth\Contracts\JWTSubjectInterface;

class User extends Entity implements
    //..
    JWTSubjectInterface
{
    /**
     * {@inheritdoc}
     */
    public function getJWTIdentifier()
    {
        return $this->id;
    }

    /**
     * {@inheritdoc}
     */
    public function getJWTCustomClaims()
    {
        return [];
    }
}

添加 \Fluent\JWTAuth\JWTGuard::class 守卫

我们需要使用 Auth 门面或服务上的 extend 方法定义 \Fluent\JWTAuth\JWTGuard::class 身份验证守卫。您应该在服务提供程序中将对 extend 方法的调用。由于 codeigniter4-authentication 已经包含了 AuthServiceProvider,我们可以将代码放在那个提供程序中。打开 \App\Providers\AuthServiceProvider

namespace App\Providers;

use Fluent\Auth\AbstractServiceProvider;
use Fluent\Auth\Facades\Auth;
use Fluent\JWTAuth\Config\Services;
use Fluent\JWTAuth\JWTGuard;

class AuthServiceProvider extends AbstractServiceProvider
{
    /**
     * {@inheritdoc}
     */
    public static function register()
    {
        Auth::extend(JWTGuard::class, function ($auth, $name, array $config) {
            return new JWTGuard(
                Services::getSharedInstance('jwt'),
                Services::getSharedInstance('request'),
                $auth->createUserProvider($config['provider']),
            );
        });
    }
}

配置 Auth 守卫

app/Config/Auth.php 文件中,您需要做出一些更改以配置 codeigniter4-authentication 以使用 jwt 守卫来支持应用程序的认证。

对该文件进行以下更改

public $guards = [
    //..
    'api' => [
        'driver' => \Fluent\JWTAuth\JWTGuard::class,
        'provider' => 'users',
    ],
];

这里我们告诉 api 守卫使用 \Fluent\JWTAuth\JWTGuard::class 驱动,并设置了 api 守卫。

接下来,我们需要将此 App\Providers\AuthServiceProvider 注册到应用程序生命周期中。打开 App\Config\Events 并添加此行

Events::on('pre_system', [\App\Providers\AuthServiceProvider::class, 'register']);

现在,我们可以使用 codeigniter4-authentication 内置的 Auth 系统,由 codeigniter4-authentication-jwt 在幕后完成工作!

添加一些基本的认证路由

首先,让我们在 app/Config/Routes.php 中添加一些路由,如下所示

$routes->group('jwt', function ($routes) {
    $routes->post('login', 'JwtauthController::login');
    $routes->post('logout', 'JwtauthController::logout', ['filter' => 'auth:api']);
    $routes->post('refresh', 'JwtauthController::refresh', ['filter' => 'auth:api']);
    $routes->match(['get', 'post'], 'user', 'JwtauthController::user', ['filter' => 'auth:api']);
});

创建 AuthController

然后创建 JwtauthController,可以手动创建或运行 spark 命令

php spark make:controller JwtauthController

然后添加以下内容

<?php

namespace App\Controllers;

use App\Controllers\BaseController;
use CodeIgniter\API\ResponseTrait;

class JwtauthController extends BaseController
{
    use ResponseTrait;

    /**
     * Get a JWT via given credentials.
     *
     * @return \CodeIgniter\Http\Response
     */
    public function login()
    {
        // Validate this credentials request.
        if (! $this->validate(['email' => 'required|valid_email', 'password' => 'required'])) {
            return $this->fail($this->validator->getErrors());
        }

        $credentials = [
            'email' => $this->request->getPost('email'),
            'password' => $this->request->getPost('password')
        ];

        if (! $token = auth('api')->attempt($credentials)) {
            return $this->fail(lang('Auth.failed'), 401);
        }

        return $this->respondWithToken($token);
    }

    /**
     * Get the authenticated User.
     *
     * @return \CodeIgniter\Http\Response
     */
    public function user()
    {
        return $this->response->setJson(auth('api')->user());
    }

    /**
     * Log the user out (Invalidate the token).
     *
     * @return \CodeIgniter\Http\Response
     */
    public function logout()
    {
        auth('api')->logout();

        return $this->response->setJson(['message' => 'Successfully logged out']);
    }

    /**
     * Refresh a token.
     *
     * @return \CodeIgniter\Http\Response
     */
    public function refresh()
    {
        return $this->respondWithToken(auth('api')->refresh());
    }

    /**
     * Get the token array structure.
     *
     * @param  string $token
     *
     * @return \CodeIgniter\Http\Response
     */
    protected function respondWithToken($token)
    {
        return $this->response->setJson([
            'access_token' => $token,
            'token_type'   => 'bearer',
            'expires_in'   => auth('api')->factory()->getTTL() * 60,
        ]);
    }
}

现在,您应该能够向登录端点(例如 http://example.dev/jwt/login)发送 POST 请求,并使用一些有效的凭据,并看到如下响应

{
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ",
    "token_type": "bearer",
    "expires_in": 3600
}

此令牌可用于对应用程序进行认证请求。

认证请求

有多种方式可以通过 http 发送令牌

授权头

Authorization: Bearer eyJhbGciOiJIUzI1NiI...

查询字符串参数

http://example.dev/me?token=eyJhbGciOiJIUzI1NiI...

POST 参数

Cookie

方法

在 Auth 守卫实例上可用的方法有。

多个守卫

如果新创建的 'api' 守卫未设置为默认守卫或您已定义多个守卫以处理认证,则在调用 auth() 时应指定守卫。

 $token = auth('api')->attempt($credentials);

attempt()

尝试使用一些凭据认证用户。

// Generate a token for the user if the credentials are valid
$token = auth('api')->attempt($credentials);

这将返回 jwt 或布尔值

login()

登录用户并返回jwt。

// Get some user from somewhere
$user = (new UserModel())->first();

// Get the token
$token = auth('api')->login($user);

user()

获取当前已认证用户。

// Get the currently authenticated user
$user = auth('api')->user();

如果用户未认证,则返回null。

userOrFail()

获取当前已认证用户或抛出异常。

try {
    $user = auth('api')->userOrFail();
} catch (\Fluent\JWTAuth\Exceptions\UserNotDefinedException $e) {
    // do something
}

如果用户未设置,则抛出Fluent\JWTAuth\Exceptions\UserNotDefinedException异常。

logout()

注销用户 - 这将使当前token失效并取消已认证用户的设置。

auth('api')->logout();

// Pass true to force the token to be blacklisted "forever"
auth('api')->logout(true);

refresh()

刷新token,这将使当前token失效。

$newToken = auth('api')->refresh();

// Pass true as the first param to force the token to be blacklisted "forever".
// The second parameter will reset the claims for the new token
$newToken = auth('api')->refresh(true, true);

invalidate()

使token失效(将其添加到黑名单)。

auth('api')->invalidate();

// Pass true as the first param to force the token to be blacklisted "forever".
auth('api')->invalidate(true);

tokenById()

根据给定的用户id获取token。

$token = auth('api')->tokenById(123);

payload()

获取原始JWT载荷。

$payload = auth('api')->payload();

// then you can access the claims directly e.g.
$payload->get('sub'); // = 123
$payload['jti']; // = 'asfe4fq434asdf'
$payload('exp') // = 123456
$payload->toArray(); // = ['sub' => 123, 'exp' => 123456, 'jti' => 'asfe4fq434asdf'] etc

validate()

验证用户的凭据。

if (auth('api')->validate($credentials)) {
    // credentials are valid
}

更高级的使用

添加自定义声明

$token = auth('api')->claims(['foo' => 'bar'])->attempt($credentials);

显式设置token

$user = auth('api')->setToken('eyJhb...')->user();

显式设置请求实例

$user = auth('api')->setRequest($request)->user();

覆盖token的TTL

$token = auth('api')->setTTL(7200)->attempt($credentials);

贡献

欢迎贡献。

许可

在MIT许可下发布,请参阅LICENSE