JWT implementation in PHP
I did a basic implementation of a JWT authentication scheme in PHP. It has no dependencies, so you can simply incorporate the two functions below in any existing application. I have been writing about JavaScript Web Token security earlier this month. It is a token standard that is well described on JWT.io. <?php function getVerifiedClaims($token,$time,$leeway,$ttl,$algorithm,$secret) { $algorithms = array('HS256'=>'sha256','HS384'=>'sha384','HS512'=>'sha512'); if (!isset($algorithms[$algorithm])) return false; $hmac = $algorithms[$algorithm]; $token = explode('.',$token); if (count($token)<3) return false; $header = json_decode(base64_decode(strtr($token[0],'-_','+/')),true); if (!$secret) return false; if ($header['typ']!='JWT') return false; if ($header['alg']!=$algorithm) return false; $signature = bin2hex(base64_decode(strtr($token[2],'-_','+/'))); if ($signature!=hash_hmac($hmac,"$token[0].$token[1]",$secret)) return false; $claims = json_decode(base64_decode(strtr($token[1],'-_','+/')),true); if (!$claims) return false; if (isset($claims['nbf']) && $time+$leeway<$claims['nbf']) return false; if (isset($claims['iat']) && $time+$leeway<$claims['iat']) return false; if (isset($claims['exp']) && $time-$leeway>$claims['exp']) return false; if (isset($claims['iat']) && !isset($claims['exp'])) { if ($time-$leeway>$claims['iat']+$ttl) return false; } return $claims; } function generateToken($claims,$time,$ttl,$algorithm,$secret) { $algorithms = array('HS256'=>'sha256','HS384'=>'sha384','HS512'=>'sha512'); $header = array(); $header['typ']='JWT'; $header['alg']=$algorithm; $token = array(); $token[0] = rtrim(strtr(base64_encode(json_encode((object)$header)),'+/','-_'),'='); $claims['iat'] = $time; $claims['exp'] = $time + $ttl; $token[1] = rtrim(strtr(base64_encode(json_encode((object)$claims)),'+/','-_'),'='); if (!isset($algorithms[$algorithm])) return false; $hmac = $algorithms[$algorithm]; $signature = hash_hmac($hmac,"$token[0].$token[1]",$secret,true); $token[2] = rtrim(strtr(base64_encode($signature),'+/','-_'),'='); return implode('.',$token); } $algorithm = 'HS256'; $secret = 'secret'; $time = time(); $leeway = 5; // seconds $ttl = 30; // seconds $claims = array('sub'=>'1234567890','name'=>'John Doe','admin'=>true); // test that the functions are working $token = generateToken($claims,$time,$ttl,$algorithm,$secret); echo "$token\n"; $claims = getVerifiedClaims($token,$time,$leeway,$ttl,$algorithm,$secret); var_dump($claims); Important notes Note that this implementation supports “HS” (HMAC based) signature algorithm with “iat” (issued at), “nbf” (not before) and “exp” (expires) fields. It does NOT support the “RS” (RSA based) and “ES” (Eliptic Curve based) signature algorithms. It also does NOT check the “iss” (issuer), “sub” (subject), “aud” (audience), “jti” (JWT token identifier) or “kid” (key identifier) fields. Please read the documentation on JWT.io to find out whether or not that matters to you. ...