IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> thinkphp6利用jwt 开发api接口及中间件使用 -> 正文阅读

[PHP知识库]thinkphp6利用jwt 开发api接口及中间件使用

安装:

composer require lcobucci/jwt

封装:app\api\service 下新建JwtAuth.php

<?php
namespace app\api\service;

use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\ValidationData;

/**
 * 单例 一次请求中所有出现jwt的地方都是一个用户
 * Class JwtAuth
 * @package app\api\service
 */
class JwtAuth
{
    // jwt token
    private $token;

    // jwt 过期时间
    private $expTime = 3600;

    // claim iss
    private $iss = 'api.ahybb.com';

    // claim aud
    private $aud = 'ahybb';

    // claim uid
    private $uid;

    // secrect
    private $secrect = '1faASDF3';

    // decode token
    private $decodeToken;

    // 单例模式JwtAuth句柄
    private static $instance;

    // 获取JwtAuth的句柄
    public static function getInstance()
    {
        if (is_null(self::$instance)) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    // 私有化构造函数
    private function __construct()
    {

    }

    // 私有化clone函数
    private function __clone()
    {
        // TODO: Implement __clone() method.
    }

    // 获取token
    public function getToken()
    {
        return (string)$this->token;
    }

    // 设置token
    public function setToken($token)
    {
        $this->token = $token;
        return $this;
    }

    // 设置uid
    public function setUid($uid)
    {
        $this->uid = $uid;
        return $this;
    }

    // 获取uid
    public function getUid()
    {
        return $this->uid;
    }

    // 编码jwt token
    public function encode()
    {
        $time = time();
        $this->token = (new Builder())->setHeader('alg', 'HS256')
            ->setIssuer($this->iss)
            ->setAudience($this->aud)
            ->setIssuedAt($time)
            ->setExpiration($time + $this->expTime)
            ->set('uid', $this->uid)
            ->sign(new Sha256(), $this->secrect)
            ->getToken();

        return $this;
    }

    public function decode()
    {
        if (!$this->decodeToken) {
            $this->decodeToken = (new Parser())->parse((string)$this->token); // Parses from a string
            $this->uid = $this->decodeToken->getClaim('uid');
        }
        return $this->decodeToken;
    }

    // validate
    public function validate()
    {
        $data = new ValidationData(); // It will use the current time to validate (iat, nbf and exp)
        $data->setIssuer($this->iss);
        $data->setAudience($this->aud);
        $data->setId($this->uid);

        return $this->decode()->validate($data);
    }

    // verify token
    public function verify()
    {
        $signer = new Sha256();
        return $this->decode()->verify($signer, $this->secrect);
    }

}

中间件:app\api\middleware 下新建api.php

<?php

namespace app\api\middleware;

use app\api\service\JwtAuth;

use think\facade\Request;
use think\Response;
use think\exception\HttpResponseException;

class Api
{
    public function handle($request, \Closure $next)
    {
        $token = Request::header('token');
        if ($token) {
            if (count(explode('.', $token)) <> 3) {
                $this->result([], 0, 'token格式错误');
            }
            $jwtAuth = JwtAuth::getInstance();
            $jwtAuth->setToken($token);
            if ($jwtAuth->validate() && $jwtAuth->verify()) {
                return $next($request);
            } else {
                $this->result([], 0, 'token已过期');
            }
        } else {
            $this->result([], 0, 'token不能为空');
        }

        return $next($request);
    }

    /**
     * 返回封装后的API数据到客户端
     * @param  mixed   $data 要返回的数据
     * @param  integer $code 返回的code
     * @param  mixed   $msg 提示信息
     * @param  string  $type 返回数据格式
     * @param  array   $header 发送的Header信息
     * @return Response
     */
    protected function result($data, int $code = 0, $msg = '', string $type = '', array $header = []): Response
    {
        $result = [
            'code' => $code,
            'msg'  => $msg,
            'time' => time(),
            'data' => $data,
        ];

        $type     = $type ?: 'json';
        $response = Response::create($result, $type)->header($header);

        throw new HttpResponseException($response);
    }

}

中间件别名:根目录下/config/middleware.php

<?php
// 中间件配置
return [
    // 别名或分组
    'alias'    => [
    	'tokencheck'=> app\api\middleware\Api::class
    ],
    // 优先级设置,此数组中的中间件会按照数组中的顺序优先执行
    'priority' => [],
];

api接口使用?

namespace app\api\controller;


use app\api\service\JwtAuth;
use app\common\model\Users;
use think\facade\Db;
use think\facade\Request;

class User extends Base
{
    /**
     * 注册控制器中间件 [登录、注册 不需要鉴权]
       另外全局中间件和应用中间件

     * @var array
     */
    protected $middleware = [
        'tokencheck' => ['except' => ['login', 'register','test']],
    ];

    /**
     * @api {post} /User/login 01、会员登录
     * @apiGroup User
     * @apiVersion 6.0.0
     * @apiDescription 系统登录接口,返回 token 用于操作需验证身份的接口

     * @apiParam (请求参数:) {string}     		username 登录用户名
     * @apiParam (请求参数:) {string}     		password 登录密码

     * @apiParam (响应字段:) {string}     		token    Token

     * @apiSuccessExample {json} 成功示例
     * {"code":1,"msg":"登录成功","time":1563525780,"data":{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhcGkuc2l5dWNtcy5jb20iLCJhdWQiOiJzaXl1Y21zX2FwcCIsImlhdCI6MTU2MzUyNTc4MCwiZXhwIjoxNTYzNTI5MzgwLCJ1aWQiOjEzfQ.prQbqT00DEUbvsA5M14HpNoUqm31aj2JEaWD7ilqXjw"}}
     * @apiErrorExample {json} 失败示例
     * {"code":0,"msg":"帐号或密码错误","time":1563525638,"data":[]}
     */
    
        public function test()
    {
        $this->result(['token' => 11111], 1, '测试','',['bcx'=>212122222]);
          
    }

    public function login(string $username, string $password)
    {
        // 校验用户名密码
        $user = Users::where('email|mobile', $username)
            ->where('password', md5($password))
            ->find();
        if (empty($user)) {
            $this->result([], 0, '帐号或密码错误');
        } else {
            if ($user['status'] == 1) {
                //获取jwt的句柄
                $jwtAuth = JwtAuth::getInstance();
                $token = $jwtAuth->setUid($user['id'])->encode()->getToken();
                //更新信息
                Users::where('id', $user['id'])
                    ->update(['last_login_time' => time(), 'last_login_ip' => Request::ip()]);
                $this->result(['token' => $token], 1, '登录成功');
            } else {
                $this->result([], 0, '用户已被禁用');
            }
        }
    }

    /**
     * @api {post} /User/register 02、会员注册
     * @apiGroup User
     * @apiVersion 6.0.0
     * @apiDescription  系统注册接口,返回是否成功的提示,需再次登录

     * @apiParam (请求参数:) {string}     		email 邮箱
     * @apiParam (请求参数:) {string}     		password 密码

     * @apiSuccessExample {json} 成功示例
     * {"code":1,"msg":"注册成功","time":1563526721,"data":[]}
     * @apiErrorExample {json} 失败示例
     * {"code":0,"msg":"邮箱已被注册","time":1563526693,"data":[]}
     */
    public function register(string $email, string $password){
        // 密码长度不能低于6位
        if (strlen($password) < 6) {
            $this->result([], 0, '密码长度不能低于6位');
        }

        // 邮箱合法性判断
        if (!is_email($email)) {
            $this->result([], 0, '邮箱格式错误');
        }

        // 防止重复
        $id = Db::name('users')->where('email|mobile', '=', $email)->find();
        if ($id) {
            $this->result([], 0, '邮箱已被注册');
        }

        // 注册入库
        $data = [];
        $data['email']           = $email;
        $data['password']        = md5($password);
        $data['last_login_time'] = $data['create_time'] = time();
        $data['create_ip']       = $data['last_login_ip'] = Request::ip();
        $data['status']          = 1;
        $data['type_id']         = 1;
        $data['sex']             = Request::post('sex') ? Request::post('sex') : 0;
        $id = Db::name('users')->insertGetId($data);
        if ($id) {
            $this->result([], 1, '注册成功');
        } else {
            $this->result([], 0, '注册失败');
        }
    }

    /**
     * @api {post} /User/index 03、会员中心首页
     * @apiGroup User
     * @apiVersion 6.0.0
     * @apiDescription  会员中心首页,返回用户个人信息

     * @apiParam (请求参数:) {string}     		token Token

     * @apiSuccessExample {json} 响应数据样例
     * {"code":1,"msg":"","time":1563517637,"data":{"id":13,"email":"test110@qq.com","password":"e10adc3949ba59abbe56e057f20f883e","sex":1,"last_login_time":1563517503,"last_login_ip":"127.0.0.1","qq":"123455","mobile":"","mobile_validated":0,"email_validated":0,"type_id":1,"status":1,"create_ip":"127.0.0.1","update_time":1563507130,"create_time":1563503991,"type_name":"注册会员"}}
     */
    public function index()
    {
        $user = Db::name('users')
            ->alias('u')
            ->leftJoin('users_type ut', 'u.type_id = ut.id')
            ->field('u.*,ut.name as type_name')
            ->where('u.id', $this->getUid())
            ->find();
        return $this->result($user, 1, '');
    }

    /**
     * @api {post} /User/editPwd 04、修改密码
     * @apiGroup User
     * @apiVersion 6.0.0
     * @apiDescription  修改会员密码,返回成功或失败提示

     * @apiParam (请求参数:) {string}     		token Token
     * @apiParam (请求参数:) {string}     		oldPassword 原密码
     * @apiParam (请求参数:) {string}     		newPassword 新密码

     * @apiSuccessExample {json} 成功示例
     * {"code":1,"msg":"密码修改成功","time":1563527107,"data":[]}
     * @apiErrorExample {json} 失败示例
     * {"code":0,"msg":"token已过期","time":1563527082,"data":[]}
     */
    public function editPwd(string $oldPassword, string $newPassword){
        // 密码长度不能低于6位
        if (strlen($newPassword) < 6) {
            $this->result([], 0, '密码长度不能低于6位');
        }

        // 查看原密码是否正确
        $user = Users::where('id', $this->getUid())
            ->where('password', md5($oldPassword))
            ->find();
        if (!$user) {
            $this->result([], 0, '原密码输入有误');
        }

        //更新信息
        $user = Users::find($this->getUid());
        $user->password = md5($newPassword);
        $user->save();
        $this->result([], 1, '密码修改成功');
    }

    /**
     * @api {post} /User/editInfo 05、修改信息
     * @apiGroup User
     * @apiVersion 6.0.0
     * @apiDescription  修改用户信息,返回成功或失败提示

     * @apiParam (请求参数:) {string}     		token Token
     * @apiParam (请求参数:) {string}     		sex 性别 [1男/0女]
     * @apiParam (请求参数:) {string}     		qq  qq
     * @apiParam (请求参数:) {string}     		mobile  手机号

     * @apiSuccessExample {json} 成功示例
     * {"code":0,"msg":"修改成功","time":1563507660,"data":[]}
     * @apiErrorExample {json} 失败示例
     * {"code":0,"msg":"token已过期","time":1563527082,"data":[]}
     */
    public function editInfo(){
        $data['sex']    = trim(Request::param("sex"));
        $data['qq']     = trim(Request::param("qq"));
        $data['mobile'] = trim(Request::param("mobile"));
        if ($data['mobile']) {
            // 不可和其他用户的一致
            $id = Users::
                where('mobile', $data['mobile'])
                ->where('id', '<>', $this->getUid())
                ->find();
            if ($id) {
                $this->result([], 0, '手机号已存在');
            }
        }
        // 更新信息
        Users::where('id', $this->getUid())
            ->update($data);
        $this->result([], 0, '修改成功');
    }

    /**
     * 获取用户id
     * @return mixed
     */
    protected function getUid(){
        $jwtAuth = JwtAuth::getInstance();
        return $jwtAuth->getUid();
    }
}

  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2021-08-17 15:09:09  更:2021-08-17 15:09:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/13 12:07:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码