Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
imi
imi
提交
297f5f1b
imi
项目概览
imi
/
imi
8 个月 前同步成功
通知
53
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
imi
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
297f5f1b
编写于
7月 14, 2021
作者:
weixin_47267244
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
imi-jwt 组件兼容支持 PHP 8.0
上级
9d8f588e
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
216 addition
and
81 deletion
+216
-81
composer.json
composer.json
+1
-1
doc/components/httpserver/jwt.md
doc/components/httpserver/jwt.md
+5
-4
src/Components/jwt/composer.json
src/Components/jwt/composer.json
+1
-1
src/Components/jwt/src/Aop/JWTValidationAop.php
src/Components/jwt/src/Aop/JWTValidationAop.php
+79
-28
src/Components/jwt/src/Bean/JWT.php
src/Components/jwt/src/Bean/JWT.php
+106
-24
src/Components/jwt/src/Facade/JWT.php
src/Components/jwt/src/Facade/JWT.php
+4
-3
src/Components/jwt/src/Model/JWTConfig.php
src/Components/jwt/src/Model/JWTConfig.php
+3
-3
src/Components/jwt/src/Util/Builder.php
src/Components/jwt/src/Util/Builder.php
+0
-7
src/Components/jwt/src/Util/Parser.php
src/Components/jwt/src/Util/Parser.php
+0
-7
src/Components/jwt/tests/Unit/JWTTest.php
src/Components/jwt/tests/Unit/JWTTest.php
+17
-3
未找到文件。
composer.json
浏览文件 @
297f5f1b
...
...
@@ -60,7 +60,7 @@
"test-mqtt"
:
"tests/phpunit -c src/Components/mqtt/tests/phpunit.xml"
,
"test-smarty"
:
"tests/phpunit -c src/Components/smarty/tests/phpunit.xml"
,
"test-components"
:
[
"
(php -r
\"
exit(version_compare(PHP_VERSION, '8.0', '<') ? 0 : 1);
\"
&& composer test-jwt) || echo 'skip jwt'
"
,
"
composer test-jwt
"
,
"composer test-queue"
,
"composer test-amqp"
,
"composer test-kafka"
,
...
...
doc/components/httpserver/jwt.md
浏览文件 @
297f5f1b
...
...
@@ -75,7 +75,7 @@ $data = [
'memberId'
=>
19260817
,
];
$token
=
JWT
::
getToken
(
$data
);
// Token 对象
$tokenContent
=
$token
->
__
toString
();
// Token 字符串
$tokenContent
=
$token
->
toString
();
// Token 字符串
```
指定名称:
...
...
@@ -87,7 +87,7 @@ $data = [
'memberId'
=>
19260817
,
];
$token
=
JWT
::
getToken
(
$data
,
'a'
);
// Token 对象
$tokenContent
=
$token
->
__
toString
();
// Token 字符串
$tokenContent
=
$token
->
toString
();
// Token 字符串
```
自定义处理:
...
...
@@ -102,7 +102,7 @@ $token = JWT::getToken($data, 'a', function(\Lcobucci\JWT\Builder $builder){
// 可以针对该对象做一些操作
$builder
->
withClaim
(
'aaa'
,
'bbb'
);
});
// Token 对象
$tokenContent
=
$token
->
__
toString
();
// Token 字符串
$tokenContent
=
$token
->
toString
();
// Token 字符串
```
### 验证 Token
...
...
@@ -114,7 +114,8 @@ use \Imi\JWT\Facade\JWT;
/** @var \Lcobucci\JWT\Token $token */
$token
=
JWT
::
parseToken
(
$jwt
);
// 仅验证是否合法
// $token = JWT::parseToken($jwt, 'a'); // 指定配置名称
$data
=
$token
->
getClaim
(
'data'
);
// 获取往token里丢的数据
$data
=
$token
->
getClaim
(
'data'
);
// 获取往token里丢的数据,PHP <= 7.3
$data
=
$token
->
claim
()
->
get
(
'data'
);
// 获取往token里丢的数据,PHP >= 7.4
// 验证有效期、id、issuer、audience、subject
$validationData
=
new
\
Lcobucci\JWT\ValidationData
;
...
...
src/Components/jwt/composer.json
浏览文件 @
297f5f1b
...
...
@@ -4,7 +4,7 @@
"license"
:
"MIT"
,
"description"
:
"在 imi 框架中非常方便地接入 jwt"
,
"require"
:
{
"lcobucci/jwt"
:
"
3.3.*
"
"lcobucci/jwt"
:
"
^3.4.0|^4.1.0
"
},
"require-dev"
:
{},
"autoload"
:
{
...
...
src/Components/jwt/src/Aop/JWTValidationAop.php
浏览文件 @
297f5f1b
...
...
@@ -17,6 +17,14 @@ use Imi\JWT\Exception\InvalidTokenException;
use
Imi\RequestContext
;
use
Imi\Util\ClassObject
;
use
Imi\Util\Http\Consts\RequestHeader
;
use
Lcobucci\Clock\FrozenClock
;
use
Lcobucci\JWT\Configuration
;
use
Lcobucci\JWT\Signer\Key\InMemory
;
use
Lcobucci\JWT\Validation\Constraint\IdentifiedBy
;
use
Lcobucci\JWT\Validation\Constraint\IssuedBy
;
use
Lcobucci\JWT\Validation\Constraint\LooseValidAt
;
use
Lcobucci\JWT\Validation\Constraint\PermittedFor
;
use
Lcobucci\JWT\Validation\Constraint\RelatedTo
;
/**
* @Aspect
...
...
@@ -73,41 +81,84 @@ class JWTValidationAop
$token
=
$jwt
->
parseToken
(
$jwtStr
,
$jwtValidation
->
name
??
$jwt
->
getDefault
());
// 验证
$validationData
=
new
\
Lcobucci\JWT\ValidationData
();
if
(
false
!==
$jwtValidation
->
id
)
if
(
3
===
$jwt
->
getJwtPackageVersion
())
{
$validationData
->
setId
(
$jwtValidation
->
id
??
$config
->
getId
());
}
if
(
false
!==
$jwtValidation
->
issuer
)
{
$validationData
->
setIssuer
(
$jwtValidation
->
issuer
??
$config
->
getIssuer
());
}
if
(
false
!==
$jwtValidation
->
audience
)
{
$validationData
->
setAudience
(
$jwtValidation
->
audience
??
$config
->
getAudience
());
}
if
(
false
!==
$jwtValidation
->
subject
)
{
$validationData
->
setSubject
(
$jwtValidation
->
subject
??
$config
->
getSubject
());
}
if
(
!
$token
->
validate
(
$validationData
))
{
throw
new
InvalidTokenException
();
$validationData
=
new
\
Lcobucci\JWT\ValidationData
();
if
(
false
!==
$jwtValidation
->
id
)
{
$validationData
->
setId
(
$jwtValidation
->
id
??
$config
->
getId
());
}
if
(
false
!==
$jwtValidation
->
issuer
)
{
$validationData
->
setIssuer
(
$jwtValidation
->
issuer
??
$config
->
getIssuer
());
}
if
(
false
!==
$jwtValidation
->
audience
)
{
$validationData
->
setAudience
(
$jwtValidation
->
audience
??
$config
->
getAudience
());
}
if
(
false
!==
$jwtValidation
->
subject
)
{
$validationData
->
setSubject
(
$jwtValidation
->
subject
??
$config
->
getSubject
());
}
if
(
!
$token
->
validate
(
$validationData
))
{
throw
new
InvalidTokenException
();
}
if
(
$jwtValidation
->
tokenParam
||
$jwtValidation
->
dataParam
)
{
$args
=
ClassObject
::
convertArgsToKV
(
$class
,
$joinPoint
->
getMethod
(),
$joinPoint
->
getArgs
());
if
(
$jwtValidation
->
tokenParam
)
{
$args
[
$jwtValidation
->
tokenParam
]
=
$token
;
}
if
(
$jwtValidation
->
dataParam
)
{
$data
=
$token
->
getClaim
(
$config
->
getDataName
());
$args
[
$jwtValidation
->
dataParam
]
=
$data
;
}
$args
=
array_values
(
$args
);
}
}
if
(
$jwtValidation
->
tokenParam
||
$jwtValidation
->
dataParam
)
else
{
$args
=
ClassObject
::
convertArgsToKV
(
$class
,
$joinPoint
->
getMethod
(),
$joinPoint
->
getArgs
());
if
(
$jwtValidation
->
tokenParam
)
$config
=
$jwt
->
getConfig
(
$jwtValidation
->
name
);
$configuration
=
Configuration
::
forAsymmetricSigner
(
$config
->
getSignerInstance
(),
InMemory
::
plainText
(
$config
->
getPrivateKey
()),
InMemory
::
plainText
(
$config
->
getPublicKey
()));
$constraints
=
[];
if
(
false
!==
$jwtValidation
->
id
&&
null
!==
(
$id
=
(
$jwtValidation
->
id
??
$config
->
getId
())))
{
$constraints
[]
=
new
IdentifiedBy
(
$id
);
}
if
(
false
!==
$jwtValidation
->
issuer
&&
null
!==
(
$issuer
=
(
$jwtValidation
->
issuer
??
$config
->
getIssuer
())))
{
$constraints
[]
=
new
IssuedBy
(
$issuer
);
}
if
(
false
!==
$jwtValidation
->
audience
&&
null
!==
(
$audience
=
(
$jwtValidation
->
audience
??
$config
->
getAudience
())))
{
$constraints
[]
=
new
PermittedFor
(
$audience
);
}
if
(
false
!==
$jwtValidation
->
subject
&&
null
!==
(
$subject
=
(
$jwtValidation
->
subject
??
$config
->
getSubject
())))
{
$constraints
[]
=
new
RelatedTo
(
$subject
);
}
$constraints
[]
=
new
LooseValidAt
(
new
FrozenClock
(
new
\
DateTimeImmutable
()));
if
(
$constraints
&&
!
$configuration
->
validator
()
->
validate
(
$token
,
...
$constraints
))
{
$args
[
$jwtValidation
->
tokenParam
]
=
$token
;
throw
new
InvalidTokenException
()
;
}
if
(
$jwtValidation
->
dataParam
)
if
(
$jwtValidation
->
tokenParam
||
$jwtValidation
->
dataParam
)
{
$data
=
$token
->
getClaim
(
$config
->
getDataName
());
$args
[
$jwtValidation
->
dataParam
]
=
$data
;
$args
=
ClassObject
::
convertArgsToKV
(
$class
,
$joinPoint
->
getMethod
(),
$joinPoint
->
getArgs
());
if
(
$jwtValidation
->
tokenParam
)
{
$args
[
$jwtValidation
->
tokenParam
]
=
$token
;
}
if
(
$jwtValidation
->
dataParam
)
{
$data
=
$token
->
claims
()
->
get
(
$config
->
getDataName
());
$args
[
$jwtValidation
->
dataParam
]
=
$data
;
}
$args
=
array_values
(
$args
);
}
$args
=
array_values
(
$args
);
}
return
$joinPoint
->
proceed
(
$args
??
null
);
...
...
src/Components/jwt/src/Bean/JWT.php
浏览文件 @
297f5f1b
...
...
@@ -6,9 +6,12 @@ use Imi\Bean\Annotation\Bean;
use
Imi\JWT\Exception\ConfigNotFoundException
;
use
Imi\JWT\Exception\InvalidTokenException
;
use
Imi\JWT\Model\JWTConfig
;
use
Imi\JWT\Util\Builder
;
use
Imi\JWT\Util\Parser
;
use
Lcobucci\JWT\Builder
;
use
Lcobucci\JWT\Configuration
;
use
Lcobucci\JWT\Parser
;
use
Lcobucci\JWT\Signer\Key\InMemory
;
use
Lcobucci\JWT\Token
;
use
Lcobucci\JWT\Validation\Constraint\SignedWith
;
/**
* @Bean("JWT")
...
...
@@ -104,37 +107,84 @@ class JWT
{
throw
new
ConfigNotFoundException
(
'Must option the config @app.beans.JWT.list'
);
}
$builder
=
new
Builder
();
$time
=
time
();
$builder
->
permittedFor
(
$config
->
getAudience
())
if
(
3
===
$this
->
getJwtPackageVersion
())
{
$builder
=
new
Builder
();
$time
=
time
();
$builder
->
permittedFor
(
$config
->
getAudience
())
->
relatedTo
(
$config
->
getSubject
())
->
expiresAt
(
$time
+
$config
->
getExpires
())
->
issuedBy
(
$config
->
getIssuer
())
->
canOnlyBeUsedAfter
(
$config
->
getNotBefore
())
->
identifiedBy
(
$config
->
getId
());
$issuedAt
=
$config
->
getIssuedAt
();
if
(
true
===
$issuedAt
)
{
$builder
->
issuedAt
(
$time
);
}
elseif
(
false
!==
$issuedAt
)
{
$builder
->
issuedAt
(
$issuedAt
);
$issuedAt
=
$config
->
getIssuedAt
();
if
(
true
===
$issuedAt
)
{
$builder
->
issuedAt
(
$time
);
}
elseif
(
false
!==
$issuedAt
)
{
$builder
->
issuedAt
(
$issuedAt
);
}
if
(
$headers
=
$config
->
getHeaders
())
{
foreach
(
$headers
as
$k
=>
$v
)
{
$builder
->
withHeader
(
$k
,
$v
);
}
}
$signer
=
$config
->
getSignerInstance
();
$key
=
$config
->
getPrivateKey
();
$builder
->
sign
(
$signer
,
$key
);
}
if
(
$headers
=
$config
->
getHeaders
())
else
{
foreach
(
$headers
as
$k
=>
$v
)
$configuration
=
Configuration
::
forAsymmetricSigner
(
$config
->
getSignerInstance
(),
InMemory
::
plainText
(
$config
->
getPrivateKey
()),
InMemory
::
plainText
(
$config
->
getPublicKey
()));
$builder
=
$configuration
->
builder
();
$now
=
new
\
DateTimeImmutable
();
$builder
->
permittedFor
(
$config
->
getAudience
())
->
relatedTo
(
$config
->
getSubject
())
->
expiresAt
(
$now
->
modify
(
'+'
.
(
$config
->
getExpires
()
??
0
)
.
' second'
))
->
issuedBy
(
$config
->
getIssuer
())
->
canOnlyBeUsedAfter
(
$now
->
modify
(
'+'
.
$config
->
getNotBefore
()
.
' second'
))
->
identifiedBy
(
$config
->
getId
()
??
''
);
$issuedAt
=
$config
->
getIssuedAt
();
if
(
true
===
$issuedAt
)
{
$builder
->
withHeader
(
$k
,
$v
);
$builder
->
issuedAt
(
$now
);
}
elseif
(
false
!==
$issuedAt
)
{
$builder
->
issuedAt
(
$issuedAt
);
}
if
(
$headers
=
$config
->
getHeaders
())
{
foreach
(
$headers
as
$k
=>
$v
)
{
$builder
->
withHeader
(
$k
,
$v
);
}
}
}
$signer
=
$config
->
getSignerInstance
();
$key
=
$config
->
getPrivateKey
();
$builder
->
sign
(
$signer
,
$key
);
return
$builder
;
}
public
function
getParserInstance
(
?string
$name
=
null
):
Parser
{
if
(
3
===
$this
->
getJwtPackageVersion
())
{
return
new
\
Lcobucci\JWT\Parser
();
}
else
{
$config
=
$this
->
getConfig
(
$name
);
$configuration
=
Configuration
::
forAsymmetricSigner
(
$config
->
getSignerInstance
(),
InMemory
::
plainText
(
$config
->
getPrivateKey
()),
InMemory
::
plainText
(
$config
->
getPublicKey
()));
return
$configuration
->
parser
();
}
}
/**
* 生成 Token.
*
...
...
@@ -142,7 +192,7 @@ class JWT
* @param string|null $name
* @param callable|null $beforeGetToken
*
* @return \Lcobucci\JWT\Token
* @return \Lcobucci\JWT\Token
|\Lcobucci\JWT\UnencryptedToken
*/
public
function
getToken
(
$data
,
?string
$name
=
null
,
?callable
$beforeGetToken
=
null
):
Token
{
...
...
@@ -154,7 +204,14 @@ class JWT
$config
=
$this
->
getConfig
(
$name
);
$builder
->
withClaim
(
$config
->
getDataName
(),
$data
);
return
$builder
->
getToken
();
if
(
3
===
$this
->
getJwtPackageVersion
())
{
return
$builder
->
getToken
();
}
else
{
return
$builder
->
getToken
(
$config
->
getSignerInstance
(),
InMemory
::
plainText
(
$config
->
getPrivateKey
()));
}
}
/**
...
...
@@ -163,14 +220,18 @@ class JWT
* @param string $jwt
* @param string|null $name
*
* @return \Lcobucci\JWT\Token
* @return \Lcobucci\JWT\Token
|\Lcobucci\JWT\UnencryptedToken
*/
public
function
parseToken
(
string
$jwt
,
?string
$name
=
null
):
Token
{
$token
=
(
new
Parser
())
->
parse
(
$jwt
);
$config
=
$this
->
getConfig
(
$name
);
if
(
$config
)
if
(
!
$config
)
{
throw
new
InvalidTokenException
();
}
if
(
3
===
$this
->
getJwtPackageVersion
())
{
$token
=
(
new
\
Lcobucci\JWT\Parser
())
->
parse
(
$jwt
);
$signer
=
$config
->
getSignerInstance
();
$key
=
$config
->
getPublicKey
();
if
(
!
$token
->
verify
(
$signer
,
$key
))
...
...
@@ -178,7 +239,28 @@ class JWT
throw
new
InvalidTokenException
();
}
}
else
{
$parser
=
$this
->
getParserInstance
(
$name
);
$token
=
$parser
->
parse
(
$jwt
);
$signer
=
$config
->
getSignerInstance
();
$key
=
$config
->
getPublicKey
();
$signedWith
=
new
SignedWith
(
$signer
,
InMemory
::
plainText
(
$key
));
try
{
$signedWith
->
assert
(
$token
);
}
catch
(
\
Throwable
$th
)
{
throw
new
InvalidTokenException
(
$th
->
getMessage
(),
$th
->
getCode
(),
$th
->
getPrevious
());
}
}
return
$token
;
}
public
function
getJwtPackageVersion
():
int
{
return
class_exists
(
\
Lcobucci\JWT\Token\Parser
::
class
)
?
4
:
3
;
}
}
src/Components/jwt/src/Facade/JWT.php
浏览文件 @
297f5f1b
...
...
@@ -13,9 +13,10 @@ use Imi\Facade\BaseFacade;
* @method static string|null getDefault()
* @method static \Imi\JWT\Model\JWTConfig|null getConfig(string|null $name = NULL)
* @method static \Lcobucci\JWT\Builder getBuilderInstance(string|null $name = NULL)
* @method static \Lcobucci\JWT\Token getToken(mixed $data, string|null $name = NULL, callable|null $beforeGetToken = NULL)
* @method static \Imi\JWT\Util\Parser getParserInstance(string|null $name = NULL)
* @method static \Lcobucci\JWT\Token parseToken(string $jwt, string|null $name = NULL)
* @method static \Lcobucci\JWT\Token|\Lcobucci\JWT\UnencryptedToken getToken(mixed $data, string|null $name = NULL, callable|null $beforeGetToken = NULL)
* @method static \Lcobucci\JWT\Parser getParserInstance(string|null $name = NULL)
* @method static \Lcobucci\JWT\Token|\Lcobucci\JWT\UnencryptedToken parseToken(string $jwt, string|null $name = NULL)
* @method static int getJwtPackageVersion()
*/
abstract
class
JWT
extends
BaseFacade
{
...
...
src/Components/jwt/src/Model/JWTConfig.php
浏览文件 @
297f5f1b
...
...
@@ -66,7 +66,7 @@ class JWTConfig
*
* @var int
*/
private
$notBefore
;
private
$notBefore
=
0
;
/**
* JWT 发出时间
...
...
@@ -238,7 +238,7 @@ class JWTConfig
*
* @return string
*/
public
function
getDataName
()
public
function
getDataName
()
:
string
{
return
$this
->
dataName
;
}
...
...
@@ -248,7 +248,7 @@ class JWTConfig
*
* @return int
*/
public
function
getNotBefore
()
public
function
getNotBefore
()
:
int
{
return
$this
->
notBefore
;
}
...
...
src/Components/jwt/src/Util/Builder.php
已删除
100644 → 0
浏览文件 @
9d8f588e
<?php
namespace
Imi\JWT\Util
;
class
Builder
extends
\
Lcobucci\JWT\Builder
{
}
src/Components/jwt/src/Util/Parser.php
已删除
100644 → 0
浏览文件 @
9d8f588e
<?php
namespace
Imi\JWT\Util
;
class
Parser
extends
\
Lcobucci\JWT\Parser
{
}
src/Components/jwt/tests/Unit/JWTTest.php
浏览文件 @
297f5f1b
...
...
@@ -18,12 +18,26 @@ class JWTTest extends TestCase
'memberId'
=>
19260817
,
];
$token
=
JWT
::
getToken
(
$data
,
null
,
function
(
Builder
$builder
)
{
$builder
->
expiresAt
(
strtotime
(
'1926-08-17'
));
if
(
3
===
JWT
::
getJwtPackageVersion
())
{
$builder
->
expiresAt
(
strtotime
(
'1926-08-17'
));
}
else
{
$builder
->
expiresAt
(
new
\
DateTimeImmutable
(
'1926-08-17'
));
}
});
$tokenStr
=
(
string
)
$token
;
$tokenStr
=
$token
->
toString
()
;
$token2
=
JWT
::
parseToken
(
$tokenStr
);
$config
=
JWT
::
getConfig
();
$this
->
assertEquals
(
json_encode
(
$data
),
json_encode
(
$token2
->
getClaim
(
$config
->
getDataName
())));
if
(
3
===
JWT
::
getJwtPackageVersion
())
{
$this
->
assertEquals
(
json_encode
(
$data
),
json_encode
(
$token2
->
getClaim
(
$config
->
getDataName
())));
}
else
{
$this
->
assertEquals
(
json_encode
(
$data
),
json_encode
(
$token2
->
claims
()
->
get
(
$config
->
getDataName
())));
}
}
/**
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录