前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PHP怎样使用JWT进行授权验证?

PHP怎样使用JWT进行授权验证?

作者头像
极客开发者
发布2022-01-18 14:24:32
3.3K0
发布2022-01-18 14:24:32
举报
文章被收录于专栏:极客开发者

本文目录

  1. 概述
  2. JWT的原理是什么?
  3. 怎样使用JWT?
  4. 客户端怎样回传JWT?
  5. 使用JWT要注意什么?

1.概述

JWT可以取代以往的基于 COOKIE/SESSION 的鉴权体系,是目前最热门跨域鉴权的解决方案,接下来从 JWT 的原理,到 PHP 示例代码,简单说明业务怎样使用 JWT 进行授权验证。

2.JWT的原理是什么?

JWT定制了一个标准,实际上就是将合法用户(一般指的是 通过 账号密码验证、短信验证,以及小程序code,或者通过其他验证逻辑 验证为合法的用户)的授权信息,加密起来,然后颁发给客户端。客户端请求需要鉴权的接口的时候,通过 HTTP报文 头部的 Authorization回传。

首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名:

代码语言:javascript
复制
HMACSHA256(
 base64UrlEncode(header) + "." +
 base64UrlEncode(payload),
 secret)

下面是 JWT包含的数据:

Header(头部)

Header 部分是一个 JSON 对象,描述 JWT 的元数据,通常是下面的样子。

代码语言:javascript
复制
{
 "alg": "HS256",
 "typ": "JWT"
}

上面的JSON对象中,alg属性表示签名的算法,默认是 HMAC SHA256;typ属性表示这个令牌(token)的类型。

Payload(负载)

此部分主要用用于存放数据,其中有官方指定的默认字段,如下:

代码语言:javascript
复制
iss:签发人
exp:过期时间
sub:主题
aud:受众
nbf:生效时间
iat:签发时间
jti:JWT编号

我们还可以添加自己的字段,但是不要我加密的信息放在这里,因为Paypload数据是谁都能解析出来的。我们一般把uid(用户id)、用户名等 开放信息存在这里

Signature(签名)

Signature是JWT最重要的部分,是对前两部分的签名,防止数据篡改。

3.怎样使用JWT?

基于JWT制定的标准,衍生出来了实现 JWT 的多个开源库 https://jwt.io/libraries ,当然我们也可以自己实现 JWT 的逻辑,但是也没有必要重复去造轮子,开发者应该利用更多的时间 去思考 有意义的事情。我们可以使用由 Google Firebase 开发的 firebase/php-jwt 库, 这个库也是目前最热门的 PHP JWT 库。下面介绍基于该库,实现常用的两种 JWT 验证方式。

HS256加密 :生成与验证JWT

使用 HS256 算法生成 JWT,这是一种对称加密,使用同一个密钥串进行加密和解密。

加密过程:

代码语言:javascript
复制
// 加密密钥,要尽可能复杂点
$key = 'kol.mama.com.cn.12334556';
$payload = [
  // 签发者
  'iss' => 'kol',
  // 主题
  'sub' => 'kol user authorization',
  // 签发时间
  'iat' => time(),
  // 生效时间
  'nbf' => time(),
  // 截止时间
  'exp' => time() + 3600 * 24 * 3,
  // 自定义字段:uid
  'uid' => 123456,
  // 自定义字段:用户名
  'user_name' => '用户1'
];
$token = JWT::encode($payload, $key);

解密过程:

代码语言:javascript
复制
$token = str_replace('Bearer ', '', $request->header('Authorization'));
$payload = JWT::decode($token, $key, ['HS256']);

RS256加密 :生成与验证JWT

这是一种非对称加密,加密和解密使用 一个 密钥对

代码语言:javascript
复制
# 生成私钥
ssh-keygen -t rsa -b 2048 -f private.key
# 使用私钥生成公钥
openssl rsa -in private.key -pubout -outform PEM -out public.key

加密过程

代码语言:javascript
复制
$priKey = file_get_contents('./private.key');
$payload = [
  // 签发者
  'iss' => 'kol',
  // 主题
  'sub' => 'kol user authorization',
  // 签发时间
  'iat' => time(),
  // 生效时间
  'nbf' => time(),
  // 截止时间
  'exp' => time() + 3600 * 24 * 3,
  // 自定义字段:uid
  'uid' => 123456,
  // 自定义字段:用户名
  'user_name' => '用户1'
];
$token = JWT::encode($payload, $priKey, 'RS256');

解密过程

代码语言:javascript
复制
$pubKey = file_get_contents('./public.key');
$token = str_replace('Bearer ', '', $request->header('Authorization'));
$payload = JWT::decode($token, $pubKey, ['RS256']);

JWT 解密(验证)

如果正常通过验证,将解析出 payload 在加密前的原数据,我们可以基础处理业务逻辑;

如果 token 已经过期,或者 token 是非法 token,这时候我们通常认为用户的操作是 非法请求,系统也将会抛出对应的异常,我们只需进行捕获并 处理相关拦截的 逻辑即可。如下示例代码:

代码语言:javascript
复制
try {
    // 验证JWT
    $token = str_replace('Bearer ', '', $request->header('Authorization'));
    $payload = JWT::decode($token, config('jwt.key'), ['HS256']);
} catch (Exception $exception) {
    // 终止业务逻辑,向客户端返回错误信息
    $data = [
        'code' => $exception->getCode() ?: 401,
        'msg' => $exception->getMessage(),
        'data' => null,
    ];
    return json($data);
}

4. 客户端怎样回传JWT?

JWT 官网的标准是将 JWT 凭证放在 HTTP 报文 头部的 Authorization 中进行请求,如向服务器请求 用户的 个人信息,HTTP报文 如下示例

代码语言:javascript
复制
GET https://api.example.com/user
Accept: application/json
Authorization: Bearer $TOKEN

5.使用JWT要注意什么?

JWT 的最大缺点是,由于服务器不保存 session 状态,因此无法在使用过程中废止某个 token,或者更改 token 的权限。也就是说,一旦 JWT 签发了,在到期之前就会始终有效,除非服务器部署额外的逻辑。

JWT 本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT 的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证(如通过手机 验证码 再次验证,或者再次输入用户密码进行验证)。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-11-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 极客开发者up 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.概述
  • 2.JWT的原理是什么?
  • 3.怎样使用JWT?
  • 4. 客户端怎样回传JWT?
  • 5.使用JWT要注意什么?
相关产品与服务
短信
腾讯云短信(Short Message Service,SMS)可为广大企业级用户提供稳定可靠,安全合规的短信触达服务。用户可快速接入,调用 API / SDK 或者通过控制台即可发送,支持发送验证码、通知类短信和营销短信。国内验证短信秒级触达,99%到达率;国际/港澳台短信覆盖全球200+国家/地区,全球多服务站点,稳定可靠。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档