启用黑名单时,在Laravel中刷新JWT令牌

时间:2017-06-21 07:00:04

标签: laravel jwt

我必须在令牌过期时刷新令牌。但是当黑名单启用时,它不允许我。

以下是jwt.php文件中的代码

# Testing Purpose so kept small

'ttl' => 10,
'refresh_ttl' => 600,
'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', true),

用于创建令牌

$token = JWTAuth::fromUser($user_obj);

用于刷新令牌(当blacklist_enabled设置为true时失败)

public function refreshToken()
{
   $token = JWTAuth::getToken();

   if(!$token)
      return Response::json(['error' => 'Token not provided'], 403);

   try {
      $token = JWTAuth::refresh($token);
   } catch (TokenInvalidException $e) {
      return Response::json(['error' => 'Session Expired'],401);
   }

   return Response::json(compact('token'));
}

我已经看到了这里讨论的问题

https://github.com/tymondesigns/jwt-auth/issues/83

https://github.com/tymondesigns/jwt-auth/issues/1160

但没有得到它的解决方案。有人可以让我知道吗

1 个答案:

答案 0 :(得分:0)

这就是我如何做到令人耳目一新的:

AuthController我有方法:

public function patchRefresh()
{
    $current_token  = JWTAuth::getToken();
    $token          = JWTAuth::refresh($current_token);

    return response()->json([
        "status" => "success",
        "code" => 200,
        'data' =>
            compact('token'),
        'messages' => ['Token refreshed!'],
    ]);
}

就我而言,我有前端 - 后端 - API架构。因此,在前端我发送每个请求AJAX后端,从会话中获取令牌并向API发送请求(通过curl),同时,需要包含带有令牌的Authorization标头。

这就是它的样子:

前端:

function tryToRefreshToken() {
    try {
        var message;
        var noToken = false;


        var response = $.ajax({
            type: "POST",
            async:false,
            url: api + "?action=refresh-token",
            success: function (response) {}
        }).responseText;

        response = JSON.parse(response);

        if ( response  ){
            message = response.messages[0];
            if (message.indexOf("no token") > -1 || message.indexOf("Expired") > -1 || message.indexOf("absent") > -1) {
                noToken = true;
            }else if (message.indexOf("Refreshed")){
                console.log("Token refreshed!");
            }else{
                console.log(message);
            }
        }else{
            console.log("No response");
        }

        if (noToken) {
            console.log("There is no valid token!");
            alert("Your session is expired... Please, login to continue. ");
                logout();
                loadNavbar();
                loadMainContent();
            }

    } catch (e) {
        console.log(e.message);
    }
}

后端:

    if ( !isset($_SESSION['token']) ){
        echo Helper::onFail(401,["There is no token provided."]);
        return;
    }

    $account_id = $_SESSION['account']['id'];
    $user_id = $_SESSION['user']['id'];

    if ( empty($user_id) || empty($account_id)){
        echo Helper::onFail(401,["There is no User or Account id provided!"]);
        return;
    }

    $url = API_ORIGIN . "api/auth/refresh";
    $headers = Helper::getHeaderAuth();
    $response = Helper::patchRequest($url,null, $headers);

//        echo json_encode($response, true); break;

    try{
        $message = "empty";

        if (isset($response['messages'])){
            $message = $response['messages']['0'];
        }else{
            $message = $response['message'];
        }

            if ( stristr($message,"expired") || stristr($message,"invalid") || stristr($message,"not create")){
                Helper::log("Message: " . $message);
                echo Helper::onFail(401, ["Expired"]);  // write

            }else if (stristr($message, "refreshed")){
                $_SESSION['token'] = trim($response['data']['token']);
                echo Helper::onSuccess($response['data']['token'], ["Refreshed"]);
                Helper::log("Refreshed token: " . implode(" ", $response['data']['token']));

            }else{

                Helper::log("Message: {$message}");
            }

    }catch (Exception $exception) {
        Helper::log("Exception: " . $exception->getMessage());
        echo Helper::onFail(401, [$exception->getMessage()]);
    }

使用的方法有:

/**
 * Perform Patch request via cURL
 * @param $url
 * @param $data
 * @param array $headers
 * @return mixed
 */
public static function patchRequest($url, $data, array $headers=[])
{
    $fields_string = "";

    //url-ify the data for the POST
    foreach($data as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
    $fields_string = rtrim($fields_string, '&');

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PATCH');
    curl_setopt($curl, CURLOPT_POSTFIELDS, $fields_string);
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    $data = curl_exec($curl);
    curl_close($curl);

    return json_decode($data,true);

}


public static function getHeaderAuth()
{
    return ["Accept: application/json", "Content-Type: application/x-www-form-urlencoded" , "Authorization: Bearer " . $_SESSION['token'] ];
}

在API上,patchRefresh方法获取旧令牌并生成具有新到期时间的新令牌。然后,我在会话中用新的令牌替换旧令牌。所以,如果用户对ex不活动。一小时,如果令牌的TTL是一小时,他将被重定向到登录。如果令牌未过期,则每次请求都会续订。