博客 / 詳情

返回

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);
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.