简体   繁体   English

如何在 PHP 中验证 JWT 签名?

[英]How to verify JWT signature in PHP?

I have a function that generates a JWT :我有一个生成 JWT 的函数:

function getToken($user, $expTime){
   $jwt = \Firebase\JWT\JWT::encode([
     'iss' => request()->getBaseUrl(),
     'sub' => "{$user['id']}",
     'exp' => $expTime,
     'iat' => time(),
     'nbf' => time(),
     'is_admin' => $user['role_id'] == 1
 
  ], getenv("SECRET_KEY"), 'HS256');
 return $jwt;
}

This function returns the below token:此函数返回以下标记:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJcL2FwaSIsInN1YiI6InVzNWIzY2M4YmRlMDc4MSIsImV4cCI6NTUxMDY1ODkyNDAwMCwiaWF0IjoxNTMwNzM4NTkwLCJuYmYiOjE1MzA3Mzg1OTAsImlzX2FkbWluIjpmYWxzZX0.3bMaxCaMprURZEDurnckZWSoDRp7ePMxZXDW0B6q6fk eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJcL2FwaSIsInN1YiI6InVzNWIzY2M4YmRlMDc4MSIsImV4cCI6NTUxMDY1ODkyNDAwMCwiaWF0IjoxNTMwNzM4NTkwLCJuYmYiOjE1MzA3Mzg1OTAsImlzX2FkbWluIjpmYWxzZX0.3bMaxCaMprURZEDurnckZWSoDRp7ePMxZXDW0B6q6fk

When I use this token to make a request I get that:当我使用此令牌发出请求时,我得到:

{
  "status": "error",
  "message": "Signature verification failed"
}

To make it work I go to https://jwt.io/ , add the key and verify it by passing the secret.为了让它工作,我去https://jwt.io/ ,添加密钥并通过传递秘密来验证它。

Then I get this token :然后我得到这个令牌:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIvYXBpIiwic3ViIjoidXM1YjNjYzhiZGUwNzgxIiwiZXhwIjo1NTEwNjU4OTI0MDAwLCJpYXQiOjE1MzA3Mzg1OTAsIm5iZiI6MTUzMDczODU5MCwiaXNfYWRtaW4iOmZhbHNlfQ.heF_L9LrFp7Hht2dbVtOMx_gdUtmPKzrMgxW1_jdWLo eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIvYXBpIiwic3ViIjoidXM1YjNjYzhiZGUwNzgxIiwiZXhwIjo1NTEwNjU4OTI0MDAwLCJpYXQiOjE1MzA3Mzg1OTAsIm5iZiI6MTUzMDczODU5MCwiaXNfYWRtaW4iOmZhbHNlfQ.heF_L9LrFp7Hht2dbVtOMx_gdUtmPKzrMgxW1_jdWLo

And this works fine.这工作正常。 But how to verify it with php code so I can send it to the user?但是如何用php代码验证它以便我可以将它发送给用户?

Code for response:响应代码:

function loginUser($email, $password) {

    try {
        // Connecting to databas
        $db = new db();
        $db = $db->connect();

        $user = findUserByEmail($email, $db);

        if(empty($user)){
            echo 'User not found';
            exit;
        }
        if(!password_verify($password, $user['password'])) {
            echo 'Password does not match';
            exit;
        } 

        $expTime = time() * 3600;

        $jwt = getToken($user, $expTime);

        // Close databse
        $db = null;
        
    } catch(PDOException $e){
        echo $e->getMessage();
    }

    return $jwt;
}

If you're landing on this page because of a "Signature verification failed" Google search, here is one thing to consider.如果您因为 Google 搜索“签名验证失败”而登陆此页面,则需要考虑一件事。 I was getting this error because there were two spaces between "Bearer" and my token in the Authorization header.我收到此错误是因为 Authorization 标头中的“Bearer”和我的令牌之间有两个空格。

Wrong:错误的:

Authorization:Bearer  eyJraWQiOiJDT2N...

Correct:正确的:

Authorization:Bearer eyJraWQiOiJDT2N...

Ok finally I made it work by changing a little the function that generates the token:好的,最后我通过稍微更改生成令牌的函数使其工作:

function getToken($user, $expTime){
    $key = "secretkey";
    $token = array(
      'iss' => request()->getBaseUrl(),
      'sub' => "{$user['id']}",
      'exp' => $expTime,
      'iat' => time(),
      'nbf' => time(),
      'is_admin' => $user['role_id'] == 1
  );
  return JWT::encode($token, $key);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM