基于PHP实现JWT登录鉴权的示例代码

目录
  • 一、什么是JWT
    • 1、简介
    • 2、JWT的组成
    • 3、JWT验证流程和特点
  • 二、相关问题
  • 三、PHP实现
    • 1、引入依赖
    • 2、功能实现
    • 3、封装工具类如下

一、什么是JWT

1、简介

JWT(JSON Web Token)是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准。

简单的说,JWT就是一种Token的编码算法,服务器端负责根据一个密码和算法生成Token,然后发给客户端,客户端只负责后面每次请求都在HTTP header里面带上这个Token,服务器负责验证这个Token是不是合法的,有没有过期等,并可以解析出subject和claim里面的数据。

2、JWT的组成

第一部分为头部(header),第二部分我们称其为载荷(payload),第三部分是签证(signature)。【中间用 . 分隔】

一个标准的JWT生成的token格式如下:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImp0aSI6IjRmMWcyM2ExMmFhMTEifQ.eyJpc3MiOiJodHRwOlwvXC9leGFtcGxlLmNvbSIsImF1ZCI6Imh0dHA6XC9cL2V4YW1wbGUub3JnIiwianRpIjoiNGYxZzIzYTEyYWExMSIsImlhdCI6MTY0MDE3MTA1MywibmJmIjoxNjQwMTcxMDU0LCJleHAiOjE2NDAxNzQ2NTMsInVpZCI6MjAsInVzZXJuYW1lIjoiTWFrZSJ9.bysUwNIyhqqEyL0JecSHdplSTfE6G6zuCsrAn6eyrQM

使用https://jwt.io/这个网站对JWT Token进行解析的结果如下

3、JWT验证流程和特点

验证流程:

① 在头部信息中声明加密算法和常量, 然后把header使用json转化为字符串

② 在载荷中声明用户信息,同时还有一些其他的内容;再次使用json 把载荷部分进行转化,转化为字符串

③ 使用在header中声明的加密算法和每个项目随机生成的secret来进行加密, 把第一步分字符串和第二部分的字符串进行加密, 生成新的字符串。词字符串是独一无二的。

④ 解密的时候,只要客户端带着JWT来发起请求,服务端就直接使用secret进行解密。

特点:

① 三部分组成,每一部分都进行字符串的转化

② 解密的时候没有使用数据库,仅仅使用的是secret进行解密

③ JWT的secret千万不能泄密!

④ 不依赖数据库,而是直接根据token取出保存的用户信息,以及对token可用性校验,校验方式更加简单便捷化,单点登录更为简单。

二、相关问题

  • JWT Token需要持久化在redis、Memcached中吗?

不应该这样做,无状态的jwt变成了有状态了,背离了JWT通过算法验证的初心。

  • 在退出登录时怎样实现JWT Token失效呢?

退出登录, 只要客户端端把Token丢弃就可以了,服务器端不需要废弃Token。

  • 怎样保持客户端长时间保持登录状态?

服务器端提供刷新Token的接口, 客户端负责按一定的逻辑刷新服务器Token。

三、PHP实现

1、引入依赖

composer require lcobucci/jwt 3.*

2、功能实现

  • 签发token, 设置签发人、接收人、唯一标识、签发时间、立即生效、过期时间、用户id、用户username、签名。其中,用户id、用户username是特意存储在token中的信息,也可以增加一些其他信息,这样在解析的时候就可以直接获取到这些信息,不能是敏感数据
  • 验证令牌验证这个Token是不是合法的,有没有过期等,并可以解析出subject和claim里面的数据,传递jwt token的方式为Authorization中的Bearer Token,如下

3、封装工具类如下

<?php
/**
 * Created by PhpStorm
 * @author sxd
 */

namespace App\Utils;

use Lcobucci\JWT\Configuration;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\Signer\Key\InMemory;
use Lcobucci\JWT\Token\Plain;
use Lcobucci\JWT\Validation\Constraint\IdentifiedBy;
use Lcobucci\JWT\Validation\Constraint\IssuedBy;
use Lcobucci\JWT\Validation\Constraint\PermittedFor;
use Lcobucci\JWT\ValidationData;

class JwtUtil
{
    // jwt github: https://github.com/lcobucci/jwt     https://jwt.io/
    protected $issuer = "http://example.com";
    protected $audience = "http://example.org";
    protected $id = "4f1g23a12aa11";
    // key 是绝对不允许泄露的
    protected static $key = "8swQsm1Xb0TA0Jw5ASPwClKVZPoTyS7GvhtaW0MxzKEihs1BNpcS2q3FYMJ11111";

    /**
     * 签发令牌
     */
    public function getToken()
{
        $time = time();
        $config = self::getConfig();
        assert($config instanceof Configuration);

        // 签发token, 设置签发人、接收人、唯一标识、签发时间、立即生效、过期时间、用户id、用户username、签名
        $token = $config->builder()
            ->issuedBy($this->issuer) // Configures the issuer (iss claim)
            ->permittedFor($this->audience) // Configures the audience (aud claim)
            ->identifiedBy($this->id, true) // Configures the id (jti claim), replicating as a header item
            ->issuedAt($time) // Configures the time that the token was issue (iat claim)
            ->canOnlyBeUsedAfter($time + 1) // Configures the time that the token can be used (nbf claim)  签发x秒钟后生效
            ->expiresAt($time + 3600) // Configures the expiration time of the token (exp claim)
            ->withClaim('uid', 20) // Configures a new claim, called "uid"
            ->withClaim('username', "Make") // Configures a new claim, called "uid"
            ->getToken($config->signer(), $config->signingKey()); // Retrieves the generated token
        return $token->toString();
    }

    /**
     * 验证 jwt token 并返回其中的用户id
     * verify token
     */
    public function verifyToken_bak($token)
{
        try {
            $config = self::getConfig();
            assert($config instanceof Configuration);

            $token = $config->parser()->parse($token);
            assert($token instanceof Plain);

            //Lcobucci\JWT\Validation\Constraint\IdentifiedBy: 验证jwt id是否匹配
            //Lcobucci\JWT\Validation\Constraint\IssuedBy: 验证签发人参数是否匹配
            //Lcobucci\JWT\Validation\Constraint\PermittedFor: 验证受众人参数是否匹配
            //Lcobucci\JWT\Validation\Constraint\RelatedTo: 验证自定义cliam参数是否匹配
            //Lcobucci\JWT\Validation\Constraint\SignedWith: 验证令牌是否已使用预期的签名者和密钥签名
            //Lcobucci\JWT\Validation\Constraint\StrictValidAt: ::验证存在及其有效性的权利要求中的iat,nbf和exp(支持余地配置
            //Lcobucci\JWT\Validation\Constraint\LooseValidAt: 验证的权利要求iat,nbf和exp,当存在时(支持余地配置)

            //验证jwt id是否匹配
            $validate_jwt_id = new IdentifiedBy($this->id);
            //验证签发人url是否正确
            $validate_issued = new IssuedBy($this->issuer);
            //验证客户端url是否匹配
            $validate_aud = new PermittedFor($this->audience);
            $config->setValidationConstraints($validate_jwt_id, $validate_issued, $validate_aud);

            $constraints = $config->validationConstraints();

            if (!$config->validator()->validate($token, ...$constraints)) {
                die("token invalid!");
            }
        } catch (\Exception $e) {
            die("error:" . $e->getMessage());
        }
        $jwtInfo = $token->claims();  // 这是jwt token中存储的所有信息
        return $jwtInfo->get("uid");  // 获取uid
    }

    /**
     * 加密解密使用的配置
     * @return Configuration
     */
    public static function getConfig()
{
        $configuration = Configuration::forSymmetricSigner(
        // You may use any HMAC variations (256, 384, and 512)
            new Sha256(),
            // replace the value below with a key of your own!
            InMemory::base64Encoded(self::$key)
        // You may also override the JOSE encoder/decoder if needed by providing extra arguments here
        );
        return $configuration;
    }

    /**
     * 另一种验证方法,但是已经弃用
     * verify token
     */
    public function verifyToken($token)
{
        $token = (new Parser())->parse((string)$token);
        //验证token
        $data = new ValidationData();
        $data->setIssuer($this->issuer);//验证的签发人
        $data->setAudience($this->audience);//验证的接收人
        $data->setId($this->id);//验证token标识

        if (!$token->validate($data)) {
            //token验证失败
            die("token invalid!");
        }
        $jwtInfo = $token->claims();  // 这是jwt token中存储的所有信息
        return $jwtInfo->get("uid");  // 获取uid
    }

}

以上就是基于PHP实现JWT登录鉴权的示例代码的详细内容,更多关于PHP JWT登录鉴权的资料请关注我们其它相关文章!

(0)

相关推荐

  • php JWT在web端中的使用方法教程

    解释一下JWT JWT就是一个字符串,经过加密处理与校验处理的字符串,由三个部分组成.基于token的身份验证可以替代传统的cookie+session身份验证方法.三个部分分别如下: header.payload.signature header部分组成 header 格式为: { "typ":"JWT", "alg":"HS256" } 这就是一个json串,两个字段都是必须的,alg字段指定了生成signature的算法

  • php实现JWT验证的实例教程

    JWT,全称 Json web token,是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景.JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密. php实现JWT,本例使用thinkphp框架,代码如下: 在vendor包中建立Jwt.

  • php实现JWT(json web token)鉴权实例详解

    JWT是什么 JWT是json web token缩写.它将用户信息加密到token里,服务器不保存任何用户信息.服务器通过使用保存的密钥验证token的正确性,只要正确即通过验证.基于token的身份验证可以替代传统的cookie+session身份验证方法. JWT由三个部分组成:header.payload.signature 以下示例以JWT官网为例 header部分: { "alg": "HS256", "typ": "JWT

  • php 后端实现JWT认证方法示例

    JWT是什么 JWT是json web token缩写.它将用户信息加密到token里,服务器不保存任何用户信息.服务器通过使用保存的密钥验证token的正确性,只要正确即通过验证.基于token的身份验证可以替代传统的cookie+session身份验证方法. 它定义了一种用于简洁,自包含的用于通信双方之间以 JSON 对象的形式安全传递信息的方法.JWT 可以使用 HMAC 算法或者是 RSA 的公钥密钥对进行签名.它具备两个特点: 简洁(Compact):可以通过URL, POST 参数或

  • PHP JWT初识及其简单示例

    一直没有好好看过jwt,直到前两天要做web验证,朋友给我推荐了jwt.才发现jwt已经被大家广泛的应用了.看来我有点out了.哈哈,趁着这个世界来好好看看这个. JWT(JSON Web Token), 顾名思义就是可以在Web上传输的token,这种token是用JSON格式进行format的.它是一个开源标准(RFC 7519),定义了一个紧凑的自包含的方式在不同实体之间安全的用JSON格式传输信息. 由于现在很多项目都是前后端分离,restful api模式.所以传统的session模式

  • PHP实现JWT的Token登录认证

    1.JWT简介 JSON Web Token(缩写 JWT),是目前最流行的跨域认证解决方案. session登录认证方案:用户从客户端传递用户名.密码等信息,服务端认证后将信息存储在session中,将session_id放到cookie中. 以后访问其他页面,自动从cookie中取到session_id,再从session中取认证信息. 另一类解决方案,将认证信息,返回给客户端,存储到客户端.下次访问其他页面,需要从客户端传递认证信息回服务端. JWT就是这类方案的代表,将认证信息保存在客户

  • 基于PHP实现JWT登录鉴权的示例代码

    目录 一.什么是JWT 1.简介 2.JWT的组成 3.JWT验证流程和特点 二.相关问题 三.PHP实现 1.引入依赖 2.功能实现 3.封装工具类如下 一.什么是JWT 1.简介 JWT(JSON Web Token)是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准. 简单的说,JWT就是一种Token的编码算法,服务器端负责根据一个密码和算法生成Token,然后发给客户端,客户端只负责后面每次请求都在HTTP header里面带上这个Token,服务器负责验证这个Token

  • 使用React-Router实现前端路由鉴权的示例代码

    React-Router 是React生态里面很重要的一环,现在React的单页应用的路由基本都是前端自己管理的,而不像以前是后端路由,React管理路由的库常用的就是就是 React-Router .本文想写一下 React-Router 的使用,但是光介绍API又太平淡了, 而且官方文档已经写得很好了 ,我这里就用一个常见的开发场景来看看 React-Router 是怎么用的吧.而我们一般的系统都会有用户访问权限的限制,某些页面可能需要用户具有一定的权限才能访问.本文就是用 React-Ro

  • SpringBoot使用Filter实现签名认证鉴权的示例代码

    情景说明 鉴权,有很多方案,如:SpringSecurity.Shiro.拦截器.过滤器等等.如果只是对一些URL进行认证鉴权的话,我们完 全没必要引入SpringSecurity或Shiro等框架,使用拦截器或过滤器就足以实现需求.         本文介绍如何使用过滤器Filter实现URL签名认证鉴权. 本人测试软硬件环境:Windows10.Eclipse.SpringBoot.JDK1.8 准备工作 第一步:在pom.xml中引入相关依赖 <dependencies> <dep

  • 基于Java实现QQ登录注册功能的示例代码

    目录 前言 实现代码 登录页面 注册页面 效果展示 前言 本文主要应用的技术有:GUI.JDBC.多线程 实现的功能具体如下: 1.登录功能 2.注册功能 3.是否隐藏密码的选择以及实现功能 4.选择性别功能 5.密码与确认密码功能 6.登录页面实时展示当前的时间 7.当登录时用户名与密码在数据库中没有相匹配的数据,则会跳转到注册页面上去. 8.同样,注册完毕后,数据会运用JDBC将数据写入数据库中,然后跳转回登录页面. 实现代码 登录页面 import javax.swing.*; impor

  • 一步步教会你微信小程序的登录鉴权

    前言 为了方便小程序应用使用微信登录态进行授权登录,微信小程序提供了登录授权的开放接口.乍一看文档,感觉文档上讲的非常有道理,但是实现起来又真的是摸不着头脑,不知道如何管理和维护登录态.本文就来手把手的教会大家在业务里如何接入和维护微信登录态,下面话不多说了,来一起看看详细的介绍吧. 接入流程 这里官方文档上的流程图已经足够清晰,我们直接就该图展开详述和补充. 首先大家看到这张图,肯定会注意到小程序进行通信交互的不止是小程序前端和我们自己的服务端,微信第三方服务端也参与其中,那么微信服务端在其中

  • koa2服务端使用jwt进行鉴权及路由权限分发的流程分析

    大体思路 后端书写REST api时,有一些api是非常敏感的,比如获取用户个人信息,查看所有用户列表,修改密码等.如果不对这些api进行保护,那么别人就可以很容易地获取并调用这些 api 进行操作. 所以对于一些api,在调用之前,我们在服务端必须先对操作者进行"身份认证",这就是所谓的鉴权. Json Web Token 简称为 JWT,它定义了一种通信双方之间以 JSON 对象的形式安全传递信息的方法.JWT 可以使用 HMAC 算法或者是 RSA 的公钥密钥对进行签名,复杂度较

  • vue-nuxt 登录鉴权的实现

    目录 介绍 链接 开始 继续往代码中走 proxy配置 请求拦截 处理不同前缀的接口 动态路由的配置 重定向及auth权限 介绍 来自mentor的梳理,做个总结和记录 链接 https://auth.nuxtjs.org/api/options/#cookie 开始 根据这个文档描述,在使用@nuxt/auth 后,如果没有显示指定cookie: false, 则auth token 会被默认存储在 cookie 里 (前面localstorage 也是一样) 所以在 login接口成功后,t

  • Go实现基于RSA加密算法的接口鉴权

    基于 RSA 加密算法的接口鉴权方案 假设接口调用者是客户端,接口提供方是服务端,则此方案存在以下规则: 客户端需要使用 RSA 算法(1024 位长度的私钥)生成公私钥,并将公钥下发给服务端: 客户端使用私钥对请求内容加签,然后需要同时将请求内容和签名一并发给服务端: 服务端收到请求后,使用客户端给的公钥对请求内容和签名进行验签,以确定请求是来自客户端的. 生成公私钥 # 生成 1024 位长度的私钥 openssl genrsa -out private-key.pem 1024 # 生成公

  • springCloud gateWay 统一鉴权的实现代码

    目录 一,统一鉴权 1.1鉴权逻辑 1.2代码实现 一,统一鉴权 内置的过滤器已经可以完成大部分的功能,但是对于企业开发的一些业务功能处理,还是需要我们自己 编写过滤器来实现的,那么我们一起通过代码的形式自定义一个过滤器,去完成统一的权限校验. 1.1 鉴权逻辑 开发中的鉴权逻辑: 当客户端第一次请求服务时,服务端对用户进行信息认证(登录) 认证通过,将用户信息进行加密形成token,返回给客户端,作为登录凭证 以后每次请求,客户端都携带认证的token 服务端对token进行解密,判断是否有效

  • 基于Vue2x的图片预览插件的示例代码

    本文介绍了基于Vue2x的图片预览插件的示例代码,分享给大家,具体如下: 先来看下Demo LiveDemo 关于开发Vue插件的几种方式 (具体请移步官网)Vue官网 MyPlugin.install = function (Vue, options) { // 1. 添加全局方法或属性 Vue.myGlobalMethod = function () { // 逻辑... } // 2. 添加全局资源 Vue.directive('my-directive', { bind (el, bin

随机推荐