Coder Social home page Coder Social logo

jwt's Issues

hyper2.2中require报错...

那么我就先装了 composer require lcobucci/jwt --ignore-platform-req=ext-sodium
然后再装了hyperf-ext/jwt --ignore-platform-req=ext-sodium 倒是没报错了 . 不知道会不会有什么问题

疑似内存泄漏问题

使用版本 hyperf-ext/jwt 版本v2.1.*

每次请求接口,经过 jwt组件HyperfExt\Jwt\Jwt::getParser(): Parser 方法时, 下面代码

    /**
     * Get the parser instance.
     */
    protected function getParser(): Parser
    {
        return new Parser();
    }

内存就会泄漏

lcobucci/jwtLcobucci\JWT\Claim\Factory::__construct(array $callbacks = []) 存在循环引用问题,内存不会被释放

引入md中的usage报错

/**
* 提供了对 JWT 编解码、刷新和失活的能力。
*
* @var ManagerInterface
*/
protected $manager;

/**
 * 提供了从请求解析 JWT 及对 JWT 进行一系列相关操作的能力。
 *
 * @var Jwt
 */
protected $jwt;

public function __construct(
    ManagerInterface $manager,
    JwtFactoryInterface $jwtFactory
) {
    $this->manager = $manager;
    $this->jwt = $jwtFactory->make();
}

错误如下:
ERROR php_swoole_server_rshutdown (ERRNO 503): Fatal error: Uncaught GuzzleHttp\Exception\ConnectException: Host is down in /Users/shangeyao/PhpstormProjects/member/vendor/hyperf/guzzle/src/CoroutineHandler.php:70
Stack trace:
#0 /Users/shangeyao/PhpstormProjects/member/vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php(35): Hyperf\Guzzle\CoroutineHandler->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
#1 /Users/shangeyao/PhpstormProjects/member/vendor/guzzlehttp/guzzle/src/Middleware.php(31): GuzzleHttp\PrepareBodyMiddleware->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
#2 /Users/shangeyao/PhpstormProjects/member/vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php(71): GuzzleHttp\Middleware::GuzzleHttp{closure}(Object(GuzzleHttp\Psr7\Request), Array)
#3 /Users/shangeyao/PhpstormProjects/member/vendor/guzzlehttp/guzzle/src/Middleware.php(63): GuzzleHttp\RedirectMiddleware->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
#4 /Users/shangeyao/PhpstormProjects/member/vendor/guzzlehttp/guzzle/src/HandlerStack.php(75): GuzzleHttp\Middleware::GuzzleHttp{closure} in /Users/shangeyao/PhpstormProjects/member/vendor/hyperf/consul/src/Client.php on line 70
PHP Fatal error: Uncaught GuzzleHttp\Exception\ConnectException: Host is down in /Users/shangeyao/PhpstormProjects/member/vendor/hyperf/guzzle/src/CoroutineHandler.php:70
Stack trace:
#0 /Users/shangeyao/PhpstormProjects/member/vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php(35): Hyperf\Guzzle\CoroutineHandler->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
#1 /Users/shangeyao/PhpstormProjects/member/vendor/guzzlehttp/guzzle/src/Middleware.php(31): GuzzleHttp\PrepareBodyMiddleware->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
#2 /Users/shangeyao/PhpstormProjects/member/vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php(71): GuzzleHttp\Middleware::GuzzleHttp{closure}(Object(GuzzleHttp\Psr7\Request), Array)
#3 /Users/shangeyao/PhpstormProjects/member/vendor/guzzlehttp/guzzle/src/Middleware.php(63): GuzzleHttp\RedirectMiddleware->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
#4 /Users/shangeyao/PhpstormProjects/member/vendor/guzzlehttp/guzzle/src/HandlerStack.php(75): GuzzleHttp\Middleware::GuzzleHttp{closure} in /Users/shangeyao/PhpstormProjects/member/vendor/hyperf/consul/src/Client.php on line 70
GuzzleHttp版本v7.2.0

关于JWT_SECRET不生效问题

image

配置
JWT_ALGO=HS256

配置
JWT_SECRET='IikK0I6LuPQg3vphKKTnIG9WtgYqPpRo7EN3ZsWUePi3VUDDhjSTBgJWPH6BCP3F'

生成token
$this->jwt->fromUser(User::first());

配置
JWT_SECRET=''

通过http请求将上边的token传入,验证token
$t = $this->jwt->check();

$t为true

看看怎么优化一下 黑名单 黑洞

我测试 refresh 兑换 token
在redis 里面 过期时间是 refresh_ttl 14天。。。
这样会在段时间 会有太多
这个能不能 将过期时间 减少 比如 阶梯式的 2小时 ?
比如,定义一个 刷新最近时间

refresh_ttl 设置为 null 会报错

HyperfExt\Jwt\Blacklist 这个类初始化 第三个参数只能为 int

public function __construct(StorageInterface $storage, int $gracePeriod, int $refreshTtl)
    {
        $this->storage = $storage;
        $this->gracePeriod = $gracePeriod;
        $this->refreshTtl = $refreshTtl;
    }

Argument 1 passed to HyperfExt\Jwt\Claims\Factory::__construct() must be of the type int or null, string given,

[ERROR] Argument 1 passed to HyperfExt\Jwt\Claims\Factory::__construct() must be of the type int or null, string given, called in /mnt/c/Users/lixwo/Project/Cattery/CatteryAPI/vendor/hyperf/di/src/Resolver/ObjectResolver.php on line 99[56] in /mnt/c/Users/lixwo/Project/Cattery/CatteryAPI/vendor/hyperf-ext/jwt/src/Claims/Factory.php
[ERROR] #0 /mnt/c/Users/lixwo/Project/Cattery/CatteryAPI/vendor/hyperf/di/src/Resolver/ObjectResolver.php(99): HyperfExt\Jwt\Claims\Factory->__construct()
#1 /mnt/c/Users/lixwo/Project/Cattery/CatteryAPI/vendor/hyperf/di/src/Resolver/ObjectResolver.php(66): Hyperf\Di\Resolver\ObjectResolver->createInstance()
#2 /mnt/c/Users/lixwo/Project/Cattery/CatteryAPI/vendor/hyperf/di/src/Resolver/ResolverDispatcher.php(62): Hyperf\Di\Resolver\ObjectResolver->resolve()
#3 /mnt/c/Users/lixwo/Project/Cattery/CatteryAPI/vendor/hyperf/di/src/Resolver/DepthGuard.php(73): Hyperf\Di\Resolver\ResolverDispatcher->Hyperf\Di\Resolver\{closure}()
        if ($token = $this->auth->guard('api')->attempt(['name' => $request_data['account'], 'password' => $request_data['password']])) {
            if ($this->auth->guard('api')->check()) {
                return $response->json(CommonUtil::jsonTemplate(0, [
                    'access_token' => $token,
                    'token_type' => 'bearer',
//                    'expires_in' => $this->auth->guard('api')->factory()->getTTL() * 60
                ], "登录成功"));
            }
        } else {
            return $response->json(CommonUtil::jsonTemplate(4033));
        }

jwt返回的token过期之后调用refresh方法提示Token has expired

hyperf-ext/jwt 版本v2.0.1

使用

<?php
    public function refresh()
    {
        $token = $this->auth->refresh();
        return $token;
    }

hyperf-ext/jwt/src/Jwt.php:line 102

    public function refresh(bool $forceForever = false): string
    {
        $this->requireToken();

        return $this->token = $this->manager
            ->refresh($this->token, $forceForever, array_merge(
                $this->getCustomClaims(),
                ($prv = $this->getPayload()->get('prv')) ? ['prv' => $prv] : []
            ))
            ->get();
    }

$this->getPayload()->get('prv') 调用 getPayload() 中调用 decode方法 第三个参数没有传递 导致 如果token过期则校验不通过

这种情况下我应该怎么通过 过期的token 换取 新的token

中间件中处理前台请求的token,一直获取失败

hyperf-ext/jwt 版本 2.0.* 升级到 2.1.*
hyperf-ext/auth 版本 2.0.* 升级到 2.1.*

代码升级中发现一个问题,执行测试用例 header 头中携带的 Authorization 是正确的,但是中间键一直在抛出异常 HyperfExt\Jwt\Exceptions\JwtException: Token could not be parsed from the request.(0),代码追踪到 src/Jwt.php:line 164 发现用了协程重写

    /**
     * Get the token.
     */
    public function getToken(): ?Token
    {
        if (empty($token = Context::get(Token::class))) {
            try {
                $this->parseToken();
                // 解析请求中的令牌,这边放在协程里面了,没有取出来,是否存在问题?
                // $token = Context::get(Token::class);
            } catch (JwtException $e) {
                $token = null;
            }
        }
        return $token;
    } 

我先在处理的方案是在中间件中预先调用了一下,解析请求中的令牌

    $this->auth->guard()->parseToken();
    $this->auth->guard()->user();

Could not create token: Builder#withClaim() is meant to be used for non-registered claims, check the documentation on how to set claim "iss"

安装了
hyperf-ext/auth
hyperf-ext/jwt
lcobucci/jwt v3.4
登录认证的时候使用了
hyperf/vendor/hyperf-ext/auth/src/Guards/JwtGuard.php
的attempt的方法,认证成功后,会进行登录获取token,调用了
hyperf/vendor/hyperf-ext/jwt/src/Codec.php的encode方法,里面
$builder->withClaim($key, $value); 语句报了标题中的错误,
而提示的意思就是这个方法只能用于未注册的claim,$payload里面的claim都是在
vendor/lcobucci/jwt/src/Token/RegisteredClaims.php
文件中注册过的,所以报了错。
应该调整为set方法

使用jwt的token获得用户信息的时候报错

按照文档配置之后,登录是成功的,但是auto/user获得用户信息时报错:

{
    "err_code": 200000,
    "err_msg": "Connection refused",
    "data": []
}

这个Connection refused是连接什么拒绝了?mysql还是redis,我没找到对应的地方

文档错误,依赖的jwt库和composer中不一致

文档写到:
该组件基于 tymon/jwt-auth,实现了完整用于 JWT 认证的能力

实际在composer.json中:

"require": {
"lcobucci/jwt": "~3.3.0",
},

而且最底部说到的两个类是什么,没看懂?

其实你升级后的hyperf都改为2.2了是没必要的

其实你升级后的hyperf都改为2.2了是没必要的,应该依赖是大于等于Hyper的2.1版本就行了,因为jwt部分依赖的lcobucci/jwt,主要影响的是jwt的内存溢出,其他并没有差别,毕竟hyperf2.2现在还不稳定

$this->auth->guard('api')->checkOrFail();不起作用

问题:

$this->auth->guard('api')->checkOrFail(); 不能拦截,并且后续打印当前用户为空

流程:

中间件代码

    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        try {
            $this->auth->guard('api')->checkOrFail();

        }catch (TokenExpiredException $e){

            var_dump(2231);
            if ($e->getMessage() == 'Token has expired') {

                return $this->response->json(
                    [
                        'code' => 401,
                        'data' => [],
                        'msg'  => '登陆失效'
                    ]
                );
//                throw new \Exception($e->getMessage());
            }

        }catch (TokenInvalidException $exception){

            return $this->response->json(
                [
                    'code' => 401,
                    'data' => [],
                    'msg'  => 'token错误'
                ]
            );
//            throw new \Exception($exception->getMessage());

        }catch (\Throwable $throwable){

            $msg = $throwable->getMessage() == 'A token is required' ? '没有TOKEN' : '请登录';
            return $this->response->json(
                [
                    'code' => 401,
                    'data' => [],
                    'msg'  => $msg
                ]
            );

        }

        return $handler->handle($request);
    }

控制器

    public function ti(TiRequest $request): array
    {
        $post = $request->validated();

        $user = $this->auth->guard('api')->user();

        var_dump($user ); 
    }

版本

"hyperf-ext/auth": "^2.1",
"hyperf-ext/jwt": "^2.1",

jwt.php配置

<?php

declare(strict_types=1);
/**
 * This file is part of hyperf-ext/jwt
 *
 * @link     https://github.com/hyperf-ext/jwt
 * @contact  [email protected]
 * @license  https://github.com/hyperf-ext/jwt/blob/master/LICENSE
 */
return [
    /*
    |--------------------------------------------------------------------------
    | JWT Authentication Secret
    |--------------------------------------------------------------------------
    |
    | Don't forget to set this in your .env file, as it will be used to sign
    | your tokens. A helper command is provided for this:
    | `php bin/hyperf.php gen:jwt-secret`
    |
    | Note: This will be used for Symmetric algorithms only (HMAC),
    | since RSA and ECDSA use a private/public key pair (See below).
    |
    | Note: This value must be encoded by base64.
    |
    */

    'secret' => env('JWT_SECRET'),

    /*
    |--------------------------------------------------------------------------
    | JWT Authentication Keys
    |--------------------------------------------------------------------------
    |
    | The algorithm you are using, will determine whether your tokens are
    | signed with a random string (defined in `JWT_SECRET`) or using the
    | following public and private keys. A helper command is provided for this:
    | `php bin/hyperf.php gen:jwt-keypair`
    |
    | Symmetric Algorithms:
    | HS256, HS384 & HS512 will use `JWT_SECRET`.
    |
    | Asymmetric Algorithms:
    | RS256, RS384 & RS512 / ES256, ES384 & ES512 will use the keys below.
    |
    */

    'keys' => [
        /*
        |--------------------------------------------------------------------------
        | Public Key
        |--------------------------------------------------------------------------
        |
        | Your public key content.
        |
        */

        'public' => env('JWT_PUBLIC_KEY'),

        /*
        |--------------------------------------------------------------------------
        | Private Key
        |--------------------------------------------------------------------------
        |
        | Your private key content.
        |
        */

        'private' => env('JWT_PRIVATE_KEY'),

        /*
        |--------------------------------------------------------------------------
        | Passphrase
        |--------------------------------------------------------------------------
        |
        | The passphrase for your private key. Can be null if none set.
        |
        | Note: This value must be encoded by base64.
        |
        */

        'passphrase' => env('JWT_PASSPHRASE'),
    ],

    /*
    |--------------------------------------------------------------------------
    | JWT time to live
    |--------------------------------------------------------------------------
    |
    | Specify the length of time (in seconds) that the token will be valid for.
    | Defaults to 1 hour.
    |
    | You can also set this to null, to yield a never expiring token.
    | Some people may want this behaviour for e.g. a mobile app.
    | This is not particularly recommended, so make sure you have appropriate
    | systems in place to revoke the token if necessary.
    | Notice: If you set this to null you should remove 'exp' element from 'required_claims' list.
    |
    */

    'ttl' => env('JWT_TTL', 1000000),

    /*
    |--------------------------------------------------------------------------
    | Refresh time to live
    |--------------------------------------------------------------------------
    |
    | Specify the length of time (in seconds) that the token can be refreshed
    | within. I.E. The user can refresh their token within a 2 week window of
    | the original token being created until they must re-authenticate.
    | Defaults to 2 weeks.
    |
    | You can also set this to null, to yield an infinite refresh time.
    | Some may want this instead of never expiring tokens for e.g. a mobile app.
    | This is not particularly recommended, so make sure you have appropriate
    | systems in place to revoke the token if necessary.
    |
    */

    'refresh_ttl' => env('JWT_REFRESH_TTL', 3600 * 24 * 14),

    /*
    |--------------------------------------------------------------------------
    | JWT hashing algorithm
    |--------------------------------------------------------------------------
    |
    | Specify the hashing algorithm that will be used to sign the token.
    |
    | possible values: HS256, HS384, HS512, RS256, RS384, RS512, ES256, ES384, ES512
    |
    */

    'algo' => env('JWT_ALGO', 'HS512'),

    /*
    |--------------------------------------------------------------------------
    | Required Claims
    |--------------------------------------------------------------------------
    |
    | Specify the required claims that must exist in any token.
    | A TokenInvalidException will be thrown if any of these claims are not
    | present in the payload.
    |
    */

    'required_claims' => [
        'iss',
        'iat',
//        'exp',
        'nbf',
        'sub',
        'jti',
    ],

    /*
    |--------------------------------------------------------------------------
    | Persistent Claims
    |--------------------------------------------------------------------------
    |
    | Specify the claim keys to be persisted when refreshing a token.
    | `sub` and `iat` will automatically be persisted, in
    | addition to the these claims.
    |
    | Note: If a claim does not exist then it will be ignored.
    |
    */

    'persistent_claims' => [
        // 'foo',
        // 'bar',
    ],

    /*
    |--------------------------------------------------------------------------
    | Lock Subject
    |--------------------------------------------------------------------------
    |
    | This will determine whether a `prv` claim is automatically added to
    | the token. The purpose of this is to ensure that if you have multiple
    | authentication models e.g. `App\User` & `App\OtherPerson`, then we
    | should prevent one authentication request from impersonating another,
    | if 2 tokens happen to have the same id across the 2 different models.
    |
    | Under specific circumstances, you may want to disable this behaviour
    | e.g. if you only have one authentication model, then you would save
    | a little on token size.
    |
    */

    'lock_subject' => true,

    /*
    |--------------------------------------------------------------------------
    | Leeway
    |--------------------------------------------------------------------------
    |
    | This property gives the jwt timestamp claims some "leeway".
    | Meaning that if you have any unavoidable slight clock skew on
    | any of your servers then this will afford you some level of cushioning.
    |
    | This applies to the claims `iat`, `nbf` and `exp`.
    |
    | Specify in seconds - only if you know you need it.
    |
    */

    'leeway' => env('JWT_LEEWAY', 0),

    /*
    |--------------------------------------------------------------------------
    | Blacklist Enabled
    |--------------------------------------------------------------------------
    |
    | In order to invalidate tokens, you must have the blacklist enabled.
    | If you do not want or need this functionality, then set this to false.
    |
    */

    'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', true),

    /*
    | -------------------------------------------------------------------------
    | Blacklist Grace Period
    | -------------------------------------------------------------------------
    |
    | When multiple concurrent requests are made with the same JWT,
    | it is possible that some of them fail, due to token regeneration
    | on every request.
    |
    | Set grace period in seconds to prevent parallel request failure.
    |
    */

    'blacklist_grace_period' => env('JWT_BLACKLIST_GRACE_PERIOD', 0),

    /*
    |--------------------------------------------------------------------------
    | Blacklist Storage
    |--------------------------------------------------------------------------
    |
    | Specify the handler that is used to store tokens in the blacklist.
    |
    */

    'blacklist_storage' => HyperfExt\Jwt\Storage\HyperfCache::class,
];

代码中间件

image

出错token

bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJodHRwOlwvXC9hcGkucm9hLmppYWJhb2xlc2hvcC5jb21cL2FwaVwvYXV0aFwvbG9naW4iLCJpYXQiOjE2MTU1MzcyMzgsImV4cCI6MTYxNjUzNzIzOCwibmJmIjoxNjE1NTM3MjM4LCJqdGkiOiJuSWR2UWNmMEhweUxxWmp5Iiwic3ViIjoxMDAwNTU1LCJwcnYiOiJmNmI3MTU0OWRiOGMyYzQyYjc1ODI3YWE0NGYwMmI3ZWU1MjlkMjRkIn0.GFCOnwmiq-YzD2F8877yr0IIyzyY_OIXIAQELRG6Ceu_FYPNd2PfdCWqm7Zw-oWGkFCNOPB2g43_XYh_uFfEug

运行结果

image

结果非常致命, 现在我的临时解决

   $user = $this->auth->guard('api')->user();
            
            if (empty($user)){
                //  more...
            }

问题发现

这个token应该是前n天生成的,今天偶然测试,发现checkOrFail不能拦截了

其他

我在 链接 中补充了常用使用方式,然后 $this->auth->guard('api')->checkOrFail(); 是大佬帮我补充的

我的.env

JWT_SECRET=MBe71G4hdUdUxROnamk4dFYkVRVY5c2BekIdvDt2ZqJuXORaQLliE8SnIPPPdRwwDLlCLTnfb4k2FdIwru/ELg==
JWT_PRIVATE_KEY="-----BEGIN ENCRYPTED PRIVATE KEY-----\n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\no6xlGScpmMrnpdgeDP3zLw==\n-----END ENCRYPTED PRIVATE KEY-----\n"
JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA5g2w4gRFyDMZNwFVsy4p\n7+Swl9Ioxscsczs3h1LAn4NYudffKAnbcAGI1U9ZDCjZx7dTdlZ0RIn+nu05aGb6\n0dA4KPIFnD3KNuakgE79xN+Fz7e1sB7Pweg7Dt/gxsxmUrUWFZggKH2uYhUuYxWc\nnx9WKmKzOsCl6NjrR22OjIQx4TrgZgWds9ERyPxV5I989V8bKQfwkC2KxJzApnby\nmb6j//9e81GF8gKgiNBVRmzv43KLD100ZxLRG91MDNX4jN3J5ch2PGB3NRlzGOHb\nZVjeqG2HwEIAMCHtqAjtdwPkuRY9Af9nJWqEiIJU/akVsqhjCtkpC1Prfj+WNzb6\n8llC/YVruqbrIQQw8vlthZchzSeAxqYJ4VJrcDE/s92c9njYLzsErucZEdL5Uel+\nuRGwTrECCgaqKKdursGTMA08kk1h6p+FlLBVn42GLwUUM/Gx3Xf2hZxaEhb8tpTQ\nHa7Rn5suCXZxeCPx+YikLk2+sIEyYA/weW8JRohnX5933bZ8sZhSH6RXPGkZn8Yh\ncP1kyczIHJ9FIRmJEcoJA786B4FQpnDRa3y7akPcl81DtfYlG6UdbLHVrmQnKiVS\ndgWYMrGzgssIMIsw8Mn+dVzpvsypDkCK9YBzFtTal7E+ly38deBFCdR29JcCYsHb\ntZ7pWxFF5BTL1H9lwztd/6kCAwEAAQ==\n-----END PUBLIC KEY-----\n"
JWT_PASSPHRASE="i29jy/McO4/RulZTm5U0WQ=="

常用使用方法总结


get带请求头登陆

请求示范:

http://127.0.0.1:9501/info?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJodHRwOlwvXC8xMjcuMC4wLjE6OTUwMVwvbG9naW4iLCJpYXQiOjE2MTIyNDEwOTIsImV4cCI6MTYxMzI0MTA5MiwibmJmIjoxNjEyMjQxMDkyLCJqdGkiOiJVNndPTFdLMktnYlVLSmdNIiwic3ViIjoyLCJwcnYiOiJmNmI3MTU0OWRiOGMyYzQyYjc1ODI3YWE0NGYwMmI3ZWU1MjlkMjRkIn0.g-mPP27i_Br2TM5TnALTGdzq97AknVXqsvwuR9SYJvPikM88AGz-etslciUkDhCrhcA1nlHeair6kSovHDpcnw

要注意是用token而不是Authorization了,并且需要你把bearer 去掉


退出

    /**
     * @Inject
     * @var AuthManager
     */
    protected $auth;

    public function logout()
    {
        $this->auth->guard('api')->logout();
    }

获取用户资料

你的Headers头中Authorization 需要拼接个bearer
完整token

bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJodHRwOlwvXC8xMjcuMC4wLjE6OTUwMVwvbG9naW4iLCJpYXQiOjE2MTIyMzkzODAsImV4cCI6MTYxMzIzOTM4MCwibmJmIjoxNjEyMjM5MzgwLCJqdGkiOiJIcGptZDA1ZzdiMGppaFZkIiwic3ViIjoyLCJwcnYiOiJmNmI3MTU0OWRiOGMyYzQyYjc1ODI3YWE0NGYwMmI3ZWU1MjlkMjRkIn0.3Glwchavjs9qL-5X3BG8VOKQeAC-Ag0OeXxA_05SdYt9sZokXDlIIJ3qE0_8Sb8qDghXXiNyA8j4GoRSx4uB6w

使用

    /**
     * @Inject
     * @var AuthManager
     */
    protected $auth;

    public function info()
    {
        $u = $this->auth->guard('api')->user();

        var_dump($u->toArray());
    }

登陆

User模型继承AuthenticatableInterface,JwtSubjectInterface

vendor/hyperf-ext/auth/src/GuardHelpers.php82行告诉你getAuthIdentifier来源

<?php


namespace App\Model;


use HyperfExt\Auth\Contracts\AuthenticatableInterface;
use HyperfExt\Jwt\Contracts\JwtSubjectInterface;

class User extends Model implements AuthenticatableInterface,JwtSubjectInterface
{
    protected $table = 'users';


    public function getJwtIdentifier()
    {
        // TODO: Implement getJwtIdentifier() method.

        return $this->getKey();
    }

    public function getJwtCustomClaims(): array
    {
        // TODO: Implement getJwtCustomClaims() method.
        return [];
    }

    public function getAuthIdentifierName(): string
    {
        // TODO: Implement getAuthIdentifierName() method.
        return 'id';
    }

    public function getAuthIdentifier()
    {
        // TODO: Implement getAuthIdentifier() method.
        return (string)$this->attributes['id'];
    }

    public function getAuthPassword(): ?string
    {
        return $this->attributes['password'];
        // TODO: Implement getAuthPassword() method.
    }

    public function getRememberToken(): ?string
    {
        // TODO: Implement getRememberToken() method.
    }

    public function setRememberToken(string $value)
    {
        // TODO: Implement setRememberToken() method.
    }

    public function getRememberTokenName(): ?string
    {
        // TODO: Implement getRememberTokenName() method.
        return  'remember_token';
    }
}

方法1.用户输入账号密码, 找到账号,用Hash::check()检测用户输入的密码和数据库的密码是否对应.用login

    /**
     * @Inject()
     * @var AuthManager
     */
    protected $auth;

    public function login()
    {
        $user = User::find(2);

        $u = $this->auth->guard('api')->login($user);

        // 如果想实现登陆时候让旧的token失效(挤掉线)

        if (empty(!$user->token)){

             make(Jwt::class)->getManager()->invalidate(new Token($user->token) );
            //make(ManagerInterface::class)->invalidate(new Token('you old token'));
        }
       
        var_dump($u);   //  token 

    }

方法2.用户输入账号密码, 用attempt

    public function login()
    {

        $z = [
            'id' => '2',
            'password'  =>  '123456'
        ];

        $u = $this->auth->guard('api')->attempt($z);

        var_dump($u);   //  token
    }

配置

安装官方协程组件

hyperf-ext/jwt JWT 组件,实现了完整用于 JWT 认证的能力
hyperf-ext/auth 移植自 illuminate/auth,基本完整的实现了 Laravel Auth 的功能特性

需要注意:

发布配置文件的时候要按照文档一点一点来

然后还有个,官方没有文档,但是需要发布一下

php bin/hyperf.php vendor:publish hyperf-ext/hashing

配置守卫

<?php

declare(strict_types=1);
/**
 * This file is part of hyperf-ext/auth.
 *
 * @link     https://github.com/hyperf-ext/auth
 * @contact  [email protected]
 * @license  https://github.com/hyperf-ext/auth/blob/master/LICENSE
 */
return [
    /*
    |--------------------------------------------------------------------------
    | Authentication Defaults
    |--------------------------------------------------------------------------
    |
    | This option controls the default authentication "guard" and password
    | reset options for your application. You may change these defaults
    | as required, but they're a perfect start for most applications.
    |
    */

    'default' => [
        'guard' => 'api',
        'passwords' => 'users',
    ],

    /*
    |--------------------------------------------------------------------------
    | Authentication Guards
    |--------------------------------------------------------------------------
    |
    | Next, you may define every authentication guard for your application.
    | Of course, a great default configuration has been defined for you
    | here which uses session storage and the Eloquent user provider.
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    */

    'guards' => [
        'web' => [
            'driver' => \HyperfExt\Auth\Guards\SessionGuard::class,
            'provider' => 'users',
            'options' => [],
        ],

        'api' => [
            'driver' => \HyperfExt\Auth\Guards\JwtGuard::class,
            'provider' => 'users',
            'options' => [],
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | User Providers
    |--------------------------------------------------------------------------
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | If you have multiple user tables or models you may configure multiple
    | sources which represent each model / table. These sources may then
    | be assigned to any extra authentication guards you have defined.
    |
    */

    'providers' => [
        'users' => [
            'driver' => \HyperfExt\Auth\UserProviders\ModelUserProvider::class,
            'options' => [
                'model' => \App\Model\User::class,
                'hash_driver' => 'bcrypt',
            ],
        ],

        // 'users' => [
        //     'driver' => \Hyperf\Auth\UserProvider\DatabaseUserProvider::class,
        //     'options' => [
        //         'connection' => 'default',
        //         'table' => 'users',
        //         'hash_driver' => 'bcrypt',
        //     ],
        // ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Resetting Passwords
    |--------------------------------------------------------------------------
    |
    | You may specify multiple password reset configurations if you have more
    | than one user table or model in the application and you want to have
    | separate password reset settings based on the specific user types.
    |
    | The expire time is the number of minutes that the reset token should be
    | considered valid. This security feature keeps tokens short-lived so
    | they have less time to be guessed. You may change this as needed.
    |
    */

    'passwords' => [
        'users' => [
            'driver' => \HyperfExt\Auth\Passwords\DatabaseTokenRepository::class,
            'provider' => 'users',
            'options' => [
                'connection' => null,
                'table' => 'password_resets',
                'expire' => 3600,
                'throttle' => 60,
                'hash_driver' => null,
            ],
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Password Confirmation Timeout
    |--------------------------------------------------------------------------
    |
    | Here you may define the amount of seconds before a password confirmation
    | times out and the user is prompted to re-enter their password via the
    | confirmation screen. By default, the timeout lasts for three hours.
    |
    */

    'password_timeout' => 10800,

    /*
    |--------------------------------------------------------------------------
    | Access Gate Policies
    |--------------------------------------------------------------------------
    |
    */

    'policies' => [
        //Model::class => Policy::class,
    ],
];

配置参数 无效

配置参数 persistent_claims 无效,查看源码也没有发现使用的地方,自定义的参数在persistent_claims配置后,在reflushToken时依旧被抛弃了

关于JWT_BLACKLIST_GRACE_PERIOD和JWT_REFRESH_TTL配置项的问题

当JWT_BLACKLIST_GRACE_PERIOD和JWT_REFRESH_TTL配置项在env文件中配置时报错

/hyperf-ext/jwt/src/ManagerFactory.php文件62,63行,从config中取出的值类型为string,Blacklist类期望的值类型为int

建议获取配置项的时候可以(int)强制转换

微信截图_20210617145628
微信截图_20210617145729

ManagerFactory.php tag可配置

private function resolveBlacklist(): Blacklist
{
$storageClass = $this->config['blacklist_storage'] ?? HyperfCache::class;
$storage = make($storageClass, [
'tag' => 'jwt.default',
]);
$gracePeriod = $this->config['blacklist_grace_period'];
$refreshTtl = $this->config['refresh_ttl'];

    return make(Blacklist::class, compact('storage', 'gracePeriod', 'refreshTtl'));
} 

这个方法中的 'tag' => 'jwt.default', 建议改成可配置项 . 改成 jwt:default: 即可.

数据多起来的时候将会不便观看
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.