Firebase JWT を使用しない JSON Web トークン
Firebase JWT を使用して JSON Web Token を作成および使用する方法に関するチュートリアルをいくつか作成しましたが、フレームワークなしで PHP のみを使用して実行することにしました.この記事では、私が独自の単純な JWT ジェネレーターをどのように作成したかを見ることができます.
このクラス内で、生成関数を作成します.この関数は、バリデータに対して使用するトークンを生成します.
generate 関数内で、encode 関数を参照します.この関数は、トークンで使用される文字列を base64 でエンコードするだけです.
この関数では、生成されたトークンを取得し、文字列、エンコーディング、そして最後に時間を検証します. 1 分間に設定したので、トークンは 1 分後に期限切れになり、目的のために使用されるようになります.
これは単純なプロジェクトですが、意図したとおりに機能します.私は過去に Firebase JWT を使用したことがありますが、ライブラリ全体をインポートする必要のない単純なソリューションが必要な場合があります.これが次の小さなプロジェクトに役立つことを願っています.私の GitHub またはその他のチュートリアルでクラスをダウンロードできます.
YouTube でこれを見る
クラスの作成
class JWT {
private $headers;
private $secret;
public function __construct()
{
$this->headers = [
'alg' => 'HS256', // we are using a SHA256 algorithm
'typ' => 'JWT', // JWT type
'iss' => 'jwt.local', // token issuer
'aud' => 'example.com' // token audience
];
$this->secret = 'thisIsASecret';
}
}
トークンを生成する
このクラス内で、生成関数を作成します.この関数は、バリデータに対して使用するトークンを生成します.
public function generate(array $payload): string
{
$headers = $this->encode(json_encode($this->headers)); // encode headers
$payload["exp"] = time() + 60; // add expiration to payload
$payload = $this->encode(json_encode($payload)); // encode payload
$signature = hash_hmac('SHA256', "$headers.$payload", $this->secret, true); // create SHA256 signature
$signature = $this->encode($signature); // encode signature
return "$headers.$payload.$signature";
}
generate 関数内で、encode 関数を参照します.この関数は、トークンで使用される文字列を base64 でエンコードするだけです.
private function encode(string $str): string
{
return rtrim(strtr(base64_encode($str), '+/', '-_'), '='); // base64 encode string
}
トークンを検証する
この関数では、生成されたトークンを取得し、文字列、エンコーディング、そして最後に時間を検証します. 1 分間に設定したので、トークンは 1 分後に期限切れになり、目的のために使用されるようになります.
public function is_valid(string $jwt): bool
{
$token = explode('.', $jwt); // explode token based on JWT breaks
if (!isset($token[1]) && !isset($token[2])) {
return false; // fails if the header and payload is not set
}
$headers = base64_decode($token[0]); // decode header, create variable
$payload = base64_decode($token[1]); // decode payload, create variable
$clientSignature = $token[2]; // create variable for signature
if (!json_decode($payload)) {
return false; // fails if payload does not decode
}
if ((json_decode($payload)->exp - time()) < 0) {
return false; // fails if expiration is greater than 0, setup for 1 minute
}
if (isset(json_decode($payload)->iss)) {
if (json_decode($headers)->iss != json_decode($payload)->iss) {
return false; // fails if issuers are not the same
}
} else {
return false; // fails if issuer is not set
}
if (isset(json_decode($payload)->aud)) {
if (json_decode($headers)->aud != json_decode($payload)->aud) {
return false; // fails if audiences are not the same
}
} else {
return false; // fails if audience is not set
}
$base64_header = $this->encode($headers);
$base64_payload = $this->encode($payload);
$signature = hash_hmac('SHA256', $base64_header . "." . $base64_payload, $this->secret, true);
$base64_signature = $this->encode($signature);
return ($base64_signature === $clientSignature);
}
すべてを一緒に入れて
class JWT
{
private $headers;
private $secret;
public function __construct()
{
$this->headers = [
'alg' => 'HS256', // we are using a SHA256 algorithm
'typ' => 'JWT', // JWT type
'iss' => 'jwt.local', // token issuer
'aud' => 'example.com' // token audience
];
$this->secret = 'thisIsASecret'; // change this to your secret code
}
public function generate(array $payload): string
{
$headers = $this->encode(json_encode($this->headers)); // encode headers
$payload["exp"] = time() + 60; // add expiration to payload
$payload = $this->encode(json_encode($payload)); // encode payload
$signature = hash_hmac('SHA256', "$headers.$payload", $this->secret, true); // create SHA256 signature
$signature = $this->encode($signature); // encode signature
return "$headers.$payload.$signature";
}
private function encode(string $str): string
{
return rtrim(strtr(base64_encode($str), '+/', '-_'), '='); // base64 encode string
}
public function is_valid(string $jwt): bool
{
$token = explode('.', $jwt); // explode token based on JWT breaks
if (!isset($token[1]) && !isset($token[2])) {
return false; // fails if the header and payload is not set
}
$headers = base64_decode($token[0]); // decode header, create variable
$payload = base64_decode($token[1]); // decode payload, create variable
$clientSignature = $token[2]; // create variable for signature
if (!json_decode($payload)) {
return false; // fails if payload does not decode
}
if ((json_decode($payload)->exp - time()) < 0) {
return false; // fails if expiration is greater than 0, setup for 1 minute
}
if (isset(json_decode($payload)->iss)) {
if (json_decode($headers)->iss != json_decode($payload)->iss) {
return false; // fails if issuers are not the same
}
} else {
return false; // fails if issuer is not set
}
if (isset(json_decode($payload)->aud)) {
if (json_decode($headers)->aud != json_decode($payload)->aud) {
return false; // fails if audiences are not the same
}
} else {
return false; // fails if audience is not set
}
$base64_header = $this->encode($headers);
$base64_payload = $this->encode($payload);
$signature = hash_hmac('SHA256', $base64_header . "." . $base64_payload, $this->secret, true);
$base64_signature = $this->encode($signature);
return ($base64_signature === $clientSignature);
}
}
結論
これは単純なプロジェクトですが、意図したとおりに機能します.私は過去に Firebase JWT を使用したことがありますが、ライブラリ全体をインポートする必要のない単純なソリューションが必要な場合があります.これが次の小さなプロジェクトに役立つことを願っています.私の GitHub またはその他のチュートリアルでクラスをダウンロードできます.
Reference
この問題について(Firebase JWT を使用しない JSON Web トークン), 我々は、より多くの情報をここで見つけました https://dev.to/thedevdrawer/json-web-tokens-without-firebase-jwt-3mopテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol