JSON Web Token uses detailed

What JWT that?

JSON Web Token (abbreviation JWT) is the most popular cross-domain authentication solutions. It is composed of three parts, the following example, the following specific explanation (JWT is not empty row, just to show below, will use the wrap looked more convenient).

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjMfQ.

SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

It is. "" Separated by a number, of three parts.
The first part is the header information,

{
  "alg": "HS256",// 加密的算法
  "typ": "JWT"// 加密的方式,填写JWT
}

The second part is the Payload, a fixed six parts and custom data composed, custom data needs to look at their own situation definition, omit the.

'iss' => 'https://www.qqdeveloper.com',// 签发人
'exp' => time() + 86400,// 过期时间(这里的有效期时间为1天)
'sub' => '主题内容',// 主题
'aud' => '受众内容',// 受众
'nbf' => $time,// 生效时间
'iat' => $time,// 签发时间
'jti' => 123,// 编号

The third part is the Signature (Is the first two parts of the encrypted come). Since the first two data portion is transparent, thus preventing leakage and falsification of data, we need encryption. First, you need to specify a key (secret). The key is to know only the server can not be disclosed to the user. Then, using the signature algorithm specified inside Header (default HMAC SHA256), generating a signature in accordance with the following equation.

第一部分的加密方式(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)

The final generation is a long string of the above paragraph.

Why use JWT

This requires from our traditional authentication mode is the traditional authentication mode is achieved based on user authentication and authorization session and cookie. The specific flow pattern as FIG.

(Fig a) and the Session authentication and authorization Cookie

1. The client sends an http request to the server.

2. server when it receives the client's request, generate a unique sessionid, there needs to generate the session is stored in the server , storage sessionid this particular session content, the default file storage is, of course, we can modify specific storage, such as database storage.
3. When the client receives this sessionid, cookie presence inside, carrying the sessionid every request.
4. After receiving the server request from the client, the client sends sessionid according to authentication and authorization.
Here also recommend you share before a session in knowledge about the cookie. Detailed session and cookie

(Figure 2) authorization token conventional

1. The client sends an http request to the server.

2. server after receiving the client's request, generates a unique token, where the server needs to store the generated token , as to how to do it, can be above session cookie and consistent manner. Cache database may also be present, such as redis, memcached.
3. The server returns the token to the client, there is a local client header request header can be stored in a cookie may also be present, but may also be present in localstorage.
4. sends a request to the server, carrying the token, the authentication or authorization server.

(Figure 3) Authentication mode the JWT

1. The client sends an http request to the server.

2.服务端根据jwt的生成规则,生成一个token,并返回给客户端,这里服务端是不需要存储的
3.客户端在接受到该token时,存在客户端。
4.客户端向服务端发送请求时,服务端对请求的token进行解析,如果发现解析出来的数据和生成的数据是一致的代表是一个合法的token,则进行相应的操作。

基于session和cookie的认证和鉴权模式有什么好与不好的地方呢?总结如下几点:

通过上面几张图,我们也大致可以看得出来,基于session都是需要服务端存储的,而JWT是不需要服务端来存储的。针对以上几点,总结如下:
一、缺点
1.容易遇到跨域问题。不同域名下是无法通过session直接来做到认证和鉴权的。
2.分布式部署的系统,需要使用共享session机制
3.容易出现csrf问题。

二、优点
1.方便灵活,服务器端直接创建一个sessionid,下发给客户端,客户端请求携带sessionid即可。
2.session存储在服务端,更加安全。
3.便于服务端清除session,让用户重新授权一次。

JWT与session有什么区别呢?

JWT是基于客户端存储的一种认证方式,然而session是基于服务端存储的一种认证方式。JWT虽然不用服务端存储了,也可以避免跨域、csrf等情况。但也存在如下几个不太好的地方。
1.无法清除认证token。由于JWT生成的token都是存储在客户端的,不能有服务端去主动清除,只有直到失效时间到了才能清除。除非服务端的逻辑做了改变。
2.存储在客户端,相对服务端,安全性更低一些。当JWT生成的token被破解,我们不便于清除该token。

如何使用JWT

这里推荐使用GitHub上面人家封装好的包,这里我使用的是firebase/php-jwt,在项目中直接使用即可安装成功。

composer require firebase/php-jwt

接下来创建一个控制器,我这里使用的ThinkPHP5.1的框架

use think\Controller;
use Firebase\JWT\JWT;

class Test extends Controller
{
    private $key = 'jwtKey';

    // 生成JWT
    public function createJwt()
    {
        $time  = time();
        $key   = $this->key;
        $token = [
            'iss' => 'https://www.qqdeveloper.com',// 签发人
            'exp' => $time + 86400,// 过期时间(这里的有效期时间为1天)
            'sub' => '主题内容',// 主题
            'aud' => '受众内容',// 受众
            'nbf' => $time,// 生效时间
            'iat' => $time,// 签发时间
            'jti' => 123,// 编号
            // 额外自定义的数据
            'data' => [
                'userName' => '编程浪子走四方'
            ]];
        // 调用生成加密方法('Payloadn内容','加密的键',['加密算法'],['加密的可以'],['JWT的header头'])
        $jwt = JWT::encode($token, $key);
        return json(['data' => $jwt]);
    }

    // 解析JWT
    public function analysisJwt()
    {
        try {
            $key = $this->key;
            $jwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9leGFtcGxlLm9yZyIsImV4cCI6MTU2ODA5NjE4MCwic3ViIjoiXHU0ZTNiXHU5ODk4XHU1MTg1XHU1YmI5IiwiYXVkIjoiXHU1M2Q3XHU0ZjE3XHU1MTg1XHU1YmI5IiwibmJmIjoxNTY4MDA5NzgwLCJpYXQiOjE1NjgwMDk3ODAsImp0aSI6MTIzLCJkYXRhIjp7InVzZXJOYW1lIjoiXHU3ZjE2XHU3YTBiXHU2ZDZhXHU1YjUwXHU4ZDcwXHU1NmRiXHU2NWI5In19.kHb_9Np0zjE25YE9czUEGvmFPYtqMJT9tuZzJTuMZl0';
            // 调用解密方法('JWT内容','解密的键,和加密时的加密键一直','加密算法')
            $decoded = JWT::decode($jwt, $key, array('HS256'));
            return json(['message' => $decoded]);
        } catch (\Exception $exception) {
            return json(['message' => $exception->getMessage()]);
        }

    }
}

通过访问第一个方法,可以生成下图一段字符串

我们将上图中的字符串复制到第二图中的$jwt变量,访问第二个方法即可解析出具体的数据。

Guess you like

Origin www.cnblogs.com/qqblog/p/11494517.html