JWT - Json Web Token

JWT是基于Json的开放标准,其定义了安全、紧凑、自包含的信息交换协议

优点

  • 跨平台、跨域、轻量级的传输
  • 可用于无状态的 身份认证、信息交换
  • JWT中的载荷信息是可信的(因为签名的存在)
  • 广泛用于分布式系统的SSO单点登录
  • OAUTH2中引入JWT能极大的简化认证流程
    • 授权服务器不需要维护Token存储
    • 资源服务器也不必要求Token检查
    • 减少了服务间的HTTP通信

缺点

  • JWT中存储信息如果过多很容易造成Token过大(可通过jti换取Redis集中存储中的用户信息 解决该问题)

组成

JWT由以下三部分Json数据的Base64Url密文,点号拼接而成

  1. Headers:包括ALGORITHM、TOKEN TYPE
  2. PAYLOAD:数据载荷,包括了三类claim信息
    • Reserved claims预定义信息(包括iss签发者exp过期时间sub请求者aud接收者nbf起效时间iat签发时间jti唯一标识
    • Public claims自定义信息
    • Private claims订阅方和接受方的协议信息
  3. Signature:签名(可选HS256(对称加密)RS256(非对称加密)两种签名算法)
	HMACSHA256(  #HS256签名算法
		base64UrlEncode(header) + "." + base64UrlEncode(payload),
		secret
	)

使用

HTTP头部带上Token信息

Authorization: Bearer jwt_token

Apache配置

Apache默认丢弃结构特殊、非base64编码的Authorization头部,所以需要额外配置下

RewriteEngine On
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]

Laravel JWT-Auth

## 安装 ##
composer require tymon/jwt-auth:0.5.*
#注册
Tymon\JWTAuth\Providers\JWTAuthServiceProvider
'JWTAuth' => 'Tymon\JWTAuth\Facades\JWTAuth'
'JWTFactory' => 'Tymon\JWTAuth\Facades\JWTFactory'
#发布配置
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider"
#生成秘钥
php artisan jwt:generate

## 配置 ##
- secret  签名秘钥
- ttl  token生存时间/min
- refresh_ttl  token刷新生存时间/min
- algo  token签名算法(维持默认即可)
- user  User模型名字空间
- identifier  对应于token subject claim的User模型标识
- required_claims  token中必须携带的chaim
- blacklist_enabled  若为false则刷新令牌后老令牌还是不会失效

## 签发令牌 ##
# 1. 快捷签发 #
$customClaims = [...]  #尽量控制chaim信息量以防token过大
$token = JWTAuth::attempt($credentials [, $customClaims])  #尝试登陆并签发令牌
$token = JWTAuth::fromUser($user [, $customClaims])  #基于用户签发令牌
# 2. 底层自定义签发 #
$payload = JWTFactory::make($customClaims)
$payload = JWTFactory::sub(xxx)->aud(xxx)->foo($customClaims)->make()
$token = JWTAuth::encode($payload)

## 认证 ##
# 1. 客户端请求提供token #
- HTTP头部方式:Authorization: Bearer JWT_Token
- Query方式:?token=JWT_Token
# 2. 解析请求中的token #
$token = JWTAuth::getToken()
$user = JWTAuth::parseToken()->authenticate()
JWTAuth::setToken('xxx.yyy.zzz') #手动设置一个jwt

## 中间件 ##
protected $routeMiddleware = [
    ...
    'jwt.auth' => 'Tymon\JWTAuth\Middleware\GetUserFromToken',
    'jwt.refresh' => 'Tymon\JWTAuth\Middleware\RefreshToken',
];
1. GetUserFromToken中间件 检查并解析token,否则抛出异常
	- tymon.jwt.absent
	- tymon.jwt.expired
	- tymon.jwt.invalid
	- tymon.jwt.user_not_found
	- tymon.jwt.valid
2. RefreshToken中间件  每次请求刷新token

猜你喜欢

转载自my.oschina.net/u/2400083/blog/978907