乐趣区

lumen框架下jwt配置多guards使用

JWT 的配置文件 config/jwt.php 翻译

ttl:token 有效期(分钟)refresh_ttl:刷新 token 时间(分钟)algo:token 签名算法
user:指向 User 模型的命名空间路径
identifier:用于从 token 的 sub 中获取用户
require_claims:必须出现在 token 的 payload 中的选项,否则会抛出 TokenInvalidException 异常
blacklist_enabled:如果该选项被设置为 false,那么我们将不能废止 token,即使我们刷新了 token,前一个 token 仍然有效
providers:完成各种任务的具体实现,如果需要的话你可以重写他们
User —— providers.user:基于 sub 获取用户的实现
JWT —— providers.jwt:加密 / 解密 token
Authentication —— providers.auth:通过证书 /ID 获取认证用户
+Storage —— providers.storage:存储 token 直到它们失效 

载荷(Payload)

我们先将用户认证的操作描述成一个 JSON 对象。其中添加了一些其他的信息,帮助今后收到这个 JWT 的服务器理解这个 JWT

 这里面的前 6 个字段都是由 JWT 的标准所定义的。sub: 该 JWT 所面向的用户(这部分就是我们使用到的。)iss: 该 JWT 的签发者
iat(issued at): 在什么时候签发的 token
exp(expires): token 什么时候过期
nbf(not before):token 在此时间之前不能被接收处理
jti:JWT ID 为 web token 提供唯一标识 

路由定义

// 登陆
$app->post('login', 'AuthController@login');

// 使用 supplier 守卫
$app->group(['prefix' => 'auth', 'middleware' => 'auth:supplier'], function ($app) {
    // 退出登陆
    $app->get('logout', 'AuthController@logout');

    // 刷新 token
    $app->get('refresh', 'AuthController@refresh');

    // 获取授权详情
    $app->get('detail', 'AuthController@detail');
});

中间件定义

namespace App\Http\Middleware;

use Closure;
use Illuminate\Contracts\Auth\Factory as Auth;

class Authenticate
{

    /**
     * The authentication guard factory instance.
     *
     * @var \Illuminate\Contracts\Auth\Factory
     */
    protected $auth;

    /**
     * Create a new middleware instance.
     *
     * @param \Illuminate\Contracts\Auth\Factory $auth
     * @return void
     */
    public function __construct(Auth $auth)
    {$this->auth = $auth;}

    /**
     * @desc 在进入控制器之前,判断并处理请求体
     * @date 2019/6/27 18:06
     * @param         $request
     * @param Closure $next
     * @param null    $guard
     */
    public function handle($request, Closure $next, $guard = null)
    {
        // 判断当前用户是否是游客(未登录)if ($this->auth->guard($guard)->guest()) {$response['code']     = '4001';
            $response['errorMsg'] = '无效令牌,需要重新获取';

            return response()->json($response);
        }

        // 判断当前用户是否登录
        if ($this->auth->guard($guard)->check()) {$user = $this->auth->guard($guard)->user(); // 获取登陆信息
            \Illuminate\Support\Facades\Auth::setUser($user); // 设置 Auth 获取的用户信息
        }

        return $next($request);
    }
}

BaseController 定义公用方法

/**
 * @desc 初始化供应商认证器
 * @date 2019/6/27 15:08
 */
protected function supplier()
{
    // 辅助函数返回守卫信息
    //return auth('supplier');

    // Auth 授权方式返回守卫信息
    return Auth::guard('supplier');
}

Token:创建

$credentials = $request->only('username', 'password');
$validate = $this->supplier()->validate($credentials); // 验证账密是否正确
$token = $this->supplier()->attempt($credentials); // 根据账户密码创建 token

# 更具用户 Model 创建 token
$user = AdminModel::find(1000000);
$token = $this->supplier()->fromUser($user);

Token:获取

$this->supplier()->getToken()

获取 token 过期时间

默认单位分钟,所以乘以 60 得到秒单位

$this->supplier()->factory()->getTTL() * 60

Payload: 载荷信息设置和获取

# 设置信息
$credentials = $request->only('username', 'password');
$customClaims = ['status' => '1', 'baz' => 'bob'];
$token = $this->supplier()->claims($customClaims)->attempt($credentials);

# 载荷的高度自定义
$payload = JWTFactory::sub(123)->aud('foo')->foo(['bar' => 'baz'])->make();
$token = JWTAuth::encode($payload);

# 获取全部信息
$this->supplier()->getPayload();
$this->supplier()->payload();

# 获取单条信息
$this->supplier()->payload()->get('exp')
$this->supplier()->getPayload()->get('exp')
$this->supplier()->getClaim('exp')

根据 token 获取用户信息

# 多守卫情况,中间件必须设置登录信息
# \Illuminate\Support\Facades\Auth::setUser($user);

# 使用自带 Auth 方法获取
$user = Auth::user();
$user = Auth::authenticate();

# 这里根据守卫获取信息
$user = $this->supplier()->user();
$user = $this->supplier()->authenticate();

# 获取授权用户 ID
$this->supplier()->id();

检查 Token 是否有效

if($this->supplier()->check()) {dd("token 是有效的");
}

根据 Token 或者请求带的 Token 获取用户信息

# 显示设置 token
$user = $this->supplier()->setToken($token)->user();

# 显示设置请求
$user = $this->supplier()->setRequest($request)->user();

Token 授权过期时间操作

// 获取授权过期时间
$ttl = $this->supplier()->factory()->getTTL() * 60;

// 获取授权过期还剩余时间
$expTime = intval($this->supplier()->payload()->get('exp')) - time();

// 重新设置过期时间, 这里等于新创建一个 token
// 和刷新 token 区别,刷新后原有 token 会失效,重新设置,原有 token 可以正常使用到过期
$credentials = ['username'=>'admin123', 'password'=>'123456'];
$token = $this->supplier()->setTTL(30)->attempt($credentials);
退出移动版