agungsugiarto / codeigniter4-authentication-jwt
为 codeigniter4 身份验证提供 JSON Web Token。
Requires
- php: ^7.3|^8.0
- agungsugiarto/codeigniter4-authentication: ^1.0|^2.0
- codeigniter4/framework: ^4.1
- lcobucci/jwt: <3.4
- nesbot/carbon: ^2.0
- tightenco/collect: ^8.19
Requires (Dev)
- mockery/mockery: >=0.9.9
- phpunit/phpunit: ^8.5|^9.4
- yoast/phpunit-polyfills: ^0.2.0
Provides
This package is auto-updated.
Last update: 2024-09-11 11:08:42 UTC
README
关于
为 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。