【问题标题】:How to parse the jwt token from controller $jwtManager->decode($jwt) using pure token ( token as a string )如何使用纯令牌(令牌作为字符串)从控制器 $jwtManager->decode($jwt) 解析 jwt 令牌
【发布时间】:2019-02-06 01:46:19
【问题描述】:

所以我正在使用 Lexik JWT 身份验证包 (Symfony 2.6) 并使用此代码成功创建了用户和令牌:

$userRegistration = new UserRegistration();
$userRegistration->setPassword($request->request->get('password'));
$userRegistration->setEmail($request->request->filter('email'));
$userRegistration->setName($request->request->filter('name'));

$token = $this->jwtManager->create($RegisteredUser);
return $this->responseProvider->ok((object) [
    'userId' => $RegisteredUser->getId(),
    'token' => $token
]);

回应:

"data": {
    "userId": 24,
    "token": "eyJhbGciOiJSUzI1NiJ9.eyJyb2xlcyI6WyJST0xFX1VTRVIiXSwidXNlcm5hbWUiOiJqYWdhZHVAaHViaWktbmV0d29yay5jb20iLCJleHAiOjE1MzYxNTI0MDAsImlhdCI6MTUzNTU0NzYwMH0.B7gnfGdW1ijAIlo9xUI0DwkGaajQAQPBkRx4ChILXRNtpLdwgEl_9gvWdiidFbSXJseS8jslOfuAFUIWATmbNBoWVa3nc8SxkIrKI29xZuN6hB7R-63RH2BKsAVPsEjgTIJoqkkCrfrSum-_d3LEf36jcXqZb8M-GRKI477IwSDDwG_7YK5v0mu8N4TATXhN0tZGNYxp8Y27EI-g0Gmj9BIiobxnqVVoBWHN5J8d-UCrXRq94ifhEiQBxkG9r_eacMscB80n1VsiN2ouKH2kX-HRxRJmcgmydxvR7RcEW-P6koTxkaZJGO6mv7auSudTFlDENpwD4OD7gtn_wMUDS_OuN8WT7rZp8lwKY9f8J9fiGyq5J-8C_HmyjW-h8WhuJmTUaKhCZ-eLgDm4Vs2IQGYkHJEDFumnIZ607MAa1CW1ChAvurqvUqJ3G4TTN4wYqAHpSKz4y8SAMLjO91cedBPH6K5i9lh5htF-mW_htem7e5ornicU_djSccgHbxfXHQYTHCnqLp7-ONfl_p4nmhIEK0wcF0gkBXbIitzeTjy7C_uf_FV1sLPE5cY3PUP42DmHrG4PuXHLv_L1EjErkrpna7pChKA_TPeiZjqMcQoE70sZw8rr8KnRF2hpABdU_M2ZXOt_vF5-T8mLmKqs0LHxE089vVC3xsAh0mUr4FE"
} 

当我尝试使用jwtManager->decode 方法解码其他控制器中的当前令牌时,问题开始了:

$jwt = "eyJhbGciOiJSUzI1NiJ9.eyJyb2xlcyI6WyJST0xFX1VTRVIiXSwidXNlcm5hbWUiOiJqYWdhZHVAaHViaWktbmV0d29yay5jb20iLCJleHAiOjE1MzYxNTI0MDAsImlhdCI6MTUzNTU0NzYwMH0.B7gnfGdW1ijAIlo9xUI0DwkGaajQAQPBkRx4ChILXRNtpLdwgEl_9gvWdiidFbSXJseS8jslOfuAFUIWATmbNBoWVa3nc8SxkIrKI29xZuN6hB7R-63RH2BKsAVPsEjgTIJoqkkCrfrSum-_d3LEf36jcXqZb8M-GRKI477IwSDDwG_7YK5v0mu8N4TATXhN0tZGNYxp8Y27EI-g0Gmj9BIiobxnqVVoBWHN5J8d-UCrXRq94ifhEiQBxkG9r_eacMscB80n1VsiN2ouKH2kX-HRxRJmcgmydxvR7RcEW-P6koTxkaZJGO6mv7auSudTFlDENpwD4OD7gtn_wMUDS_OuN8WT7rZp8lwKY9f8J9fiGyq5J-8C_HmyjW-h8WhuJmTUaKhCZ-eLgDm4Vs2IQGYkHJEDFumnIZ607MAa1CW1ChAvurqvUqJ3G4TTN4wYqAHpSKz4y8SAMLjO91cedBPH6K5i9lh5htF-mW_htem7e5ornicU_djSccgHbxfXHQYTHCnqLp7-ONfl_p4nmhIEK0wcF0gkBXbIitzeTjy7C_uf_FV1sLPE5cY3PUP42DmHrG4PuXHLv_L1EjErkrpna7pChKA_TPeiZjqMcQoE70sZw8rr8KnRF2hpABdU_M2ZXOt_vF5-T8mLmKqs0LHxE089vVC3xsAh0mUr4FE";
$test = $this->jwtManager->decode($jwt);

但是JWTManager::decode() 必须实现接口Symfony\Component\Security\Core\Authentication\Token\TokenInterface 并且不期望给出字符串。

我的目标只是从这个令牌中获取 userId,但找不到如何解码令牌的任何信息。有谁知道如何简单地解码令牌?

【问题讨论】:

    标签: php symfony jwt decode lexikjwtauthbundle


    【解决方案1】:

    请在没有任何库的情况下找到我的代码。

    function decodeJWTPayloadOnly($token){
            $tks = explode('.', $token);
            if (count($tks) != 3) {
                return null;
            }
            list($headb64, $bodyb64, $cryptob64) = $tks;
            $input=$bodyb64;
            $remainder = strlen($input) % 4;
            if ($remainder) {
                $padlen = 4 - $remainder;
                $input .= str_repeat('=', $padlen);
            }
            $input = (base64_decode(strtr($input, '-_', '+/')));
    
            if (version_compare(PHP_VERSION, '5.4.0', '>=') && !(defined('JSON_C_VERSION') && PHP_INT_SIZE > 4)) {
                $obj = json_decode($input, false, 512, JSON_BIGINT_AS_STRING);
            } else {
                $max_int_length = strlen((string) PHP_INT_MAX) - 1;
                $json_without_bigints = preg_replace('/:\s*(-?\d{'.$max_int_length.',})/', ': "$1"', $input);
                $obj = json_decode($json_without_bigints);
            }
            return $obj;
    }
    

    【讨论】:

      【解决方案2】:

      在不使用 JWT 库的情况下手动从令牌中获取信息非常简单。

      一个 JWT 字符串由 3 部分组成: base64url 编码的标头和有效负载都是 JSON“对象”和签名。所有 3 个部分都由 . 分隔。

      因此,您只需将令牌拆分为 3 个部分,在此处使用 explode 完成,然后解码 base64url 编码字符串 (base64_decode),最后解码 JSON (json_decode):

      $token = "eyJhbGciOiJSUzI1NiJ9.eyJyb2xlcyI6WyJST0xFX1VTRVIiXSwidXNlcm5hbWUiOiJqYWdhZHVAaHViaWktbmV0d29yay5jb20iLCJleHAiOjE1MzYxNTI0MDAsImlhdCI6MTUzNTU0NzYwMH0.B7gnfGdW1ijAIlo9xUI0DwkGaajQAQPBkRx4ChILXRNtpLdwgEl_9gvWdiidFbSXJseS8jslOfuAFUIWATmbNBoWVa3nc8SxkIrKI29xZuN6hB7R-63RH2BKsAVPsEjgTIJoqkkCrfrSum-_d3LEf36jcXqZb8M-GRKI477IwSDDwG_7YK5v0mu8N4TATXhN0tZGNYxp8Y27EI-g0Gmj9BIiobxnqVVoBWHN5J8d-UCrXRq94ifhEiQBxkG9r_eacMscB80n1VsiN2ouKH2kX-HRxRJmcgmydxvR7RcEW-P6koTxkaZJGO6mv7auSudTFlDENpwD4OD7gtn_wMUDS_OuN8WT7rZp8lwKY9f8J9fiGyq5J-8C_HmyjW-h8WhuJmTUaKhCZ-eLgDm4Vs2IQGYkHJEDFumnIZ607MAa1CW1ChAvurqvUqJ3G4TTN4wYqAHpSKz4y8SAMLjO91cedBPH6K5i9lh5htF-mW_htem7e5ornicU_djSccgHbxfXHQYTHCnqLp7-ONfl_p4nmhIEK0wcF0gkBXbIitzeTjy7C_uf_FV1sLPE5cY3PUP42DmHrG4PuXHLv_L1EjErkrpna7pChKA_TPeiZjqMcQoE70sZw8rr8KnRF2hpABdU_M2ZXOt_vF5-T8mLmKqs0LHxE089vVC3xsAh0mUr4FE";
      
      $tokenParts = explode(".", $token);  
      $tokenHeader = base64_decode($tokenParts[0]);
      $tokenPayload = base64_decode($tokenParts[1]);
      $jwtHeader = json_decode($tokenHeader);
      $jwtPayload = json_decode($tokenPayload);
      print $jwtPayload->username;
      

      在最后一行你有想要的信息。

      您还可以在https://jwt.io 上检查您的令牌,以查看有效负载中包含哪些字段。在那个网站上也有关于 JWT 的很好的介绍。

      【讨论】:

      • 在解码前应该检查令牌是否有效,否则会给出一些偏移错误。
      【解决方案3】:

      您可以为此使用 JWTEncoder 服务。 服务名称为lexik_jwt_authentication.jws_provider.lcobucci

      或者如果你想要类命名服务使用Lexik\Bundle\JWTAuthenticationBundle\Encoder\JWTEncoderInterface

      你要找的方法是decode()

      $jwtEncoder->decode($yourToken);

      【讨论】:

      • 但是如果 JWT 过期了,decode() 会抛出 Exception : (
      • 然后捕获异常.. :) 你不会使用无效的、过期的令牌。
      猜你喜欢
      • 2017-10-21
      • 1970-01-01
      • 2014-11-08
      • 2016-02-17
      • 2021-12-30
      • 2018-10-05
      • 2012-11-20
      • 2016-11-15
      相关资源
      最近更新 更多