使用jwt生成token

作者: 浊酒心跳 分类: PHP 发布时间: 2022-03-21 11:41 阅读: 211

一 :首先 composer 安装  firebase/php-jw

github:https://github.com/firebase/php-jwt

composer 命令 : composer require firebase/php-jwt

二:JWT安装完事  建个中间件

php think make:middleware ApiAuth

(ApiAuth  起你 想起的 名字 就OK 叫什么都行。 下面是 我的逻辑 与JWT 验证  还有 app()->user 注入 获取用户信息)

use app\common\library\Auth;
use Firebase\JWT\JWT;
use think\exception\HttpException;
 
class AdminAuth
{
    public function handle($request, \Closure $next)
    {
        // JWT 验证登录
        $auth = Auth::instance();
        $jwt = substr($request->header('Authorization'), 7);
        $user = null;
        try {
            $jwt = (array)JWT::decode($jwt, env('APP_SECRET'), ['HS256']);
            if ($jwt && $jwt['exp'] > time()) {
                $user = $auth->user($jwt);
            }
        } catch (\Exception $e) {
            $jwt = null;
        }
 
        //注入用户
        app()->auth = $auth;
        app()->user = $user;
 
        //检查访问权限
        if (!$auth->checkPublicUrl()) {
            if (empty($jwt)) {
                throw new HttpException(401, '未授权访问');
            }
 
            if (!$user) {
                throw new HttpException(401, '登录已过期,请重新登录');
            }
            if ($user['token'] != $jwt['token']) {
                throw new HttpException(401, '用户验证失败,请重新登录');
            }
        }
 
 
        return $next($request);
    }
}

三:然后在你的控制器模块目录下在建一个middleware.php文件

里面写这样的一句话 

这句话的意思就是 这个控制器模块 都需要通过中间件去验证

如果你想忽略哪个控制器方法 那么config配置下 新建 如图

当然 还有你们关心的 Auth::instance();哪里来的 这是封装的方法下面直接代码奉上

放在的位置 app\common\library\Auth;

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2022/3/9
 * Time: 15:25
 */
namespace app\common\library;

use app\api\model\User;
use Firebase\JWT\JWT;
use think\Db;
use think\facade\Request;

class Auth
{

    /**
     * user
     * @var
     */
    protected $user;


    protected $config;


    /**
     * user_id
     * @var
     */
    protected $user_id;

    /**
     * @var object 对象实例
     */
    protected static $instance;


    /**
     * 类架构函数
     * Auth constructor.
     */
    public function __construct()
    {
        if ($config = \think\facade\Config::get('auth.')) {
            $this->config = $config;
        }
    }

    /**
     * 初始化
     * @param array $options
     * @return object|static
     */
    public static function instance()
    {
        if (is_null(self::$instance)) {
            self::$instance = new static();
        }
        return self::$instance;
    }

    /**
     * 生产token
     * @param $user_id
     * @return string
     */
    public function token($user_id)
    {
        $time    = time();
        $JWT_TTL = 7 * 24 * 60 * 60;
        $token   = sha1($user_id . uniqid());

        $jwt     = [
            "user_id" => $user_id,
            "iat"     => $time,
            "token"   => $token,
            "exp"     => $time + $JWT_TTL
        ];
        if (Db::name('user')->where('id', $user_id)->setField('token', $token)) {
//            $this->clear($user_id);
            return JWT::encode($jwt, config('config.jwt.jwt_key'));
        }
        return '';
    }

    /**
     * 校验url,是否需要用户验证
     * @return bool
     */
    public function checkPublicUrl()
    {
        $urls = $this->config;
        $path = '/' . str_replace('.', '/', strtolower(Request::module() . '/' .                 Request::controller() . '/' . Request::action()));
        //判断是否需要验证
        foreach ($urls as $val) {
            foreach ($val as $value) {

                if ($path == $value) return true;
                if (strpos($path, $value)) return true;
                $position = strspn($path, $value);

                $str = substr($value, $position);
                if ($str == '*') return true;
            }

        }
        return false;
    }

    /**
     * 当前登录用户
     * @param array $jwt
     * @return array|null|\PDOStatement|string|\think\Model
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function user($jwt = [])
    {
        if ($jwt) {
            $user = User::where('id', $jwt['user_id'])->find();
            unset($user['password']);
            $this->user    = $user;
            $this->user_id = $jwt['user_id'];
        }
        return $this->user;
    }

    /**
     * 清缓存
     * @param $user_id
     */
    public function clear($user_id)
    {
        cache('user:info:' . $user_id ? $user_id : $this->user_id, null);
    }

    /**
     * 获取用户id
     * @return mixed
     */
    public function getUserId()
    {
        return $this->user_id;
    }

}

 然后在你的登陆接口 返回 JWT的token  不返回 前端拿不到token 怎么调你的接口呢 你说是吧

use 引入 上边封装的 方法

use app\common\library\Auth;

$auth = Auth::instance();
$token = $auth->token($user_info['id']);


转载自https://blog.csdn.net/qq_42678049/article/details/101369511

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

发表评论