
Implementasi Delphi dari JWT (JSON Web Token) dan Jose (JSON Object dan Enkripsi) Spesifikasi Suite. Perpustakaan ini mendukung serialisasi JWS (Dukungan JWE direncanakan) dengan beberapa algoritma Jose.

Sebelum Delphi 10 Seattle, algoritma HMAC-SHA menggunakan OpenSSL melalui Perpustakaan Indy, jadi untuk menghasilkan token Anda harus memiliki DLL OpenSSL di sistem server Anda.
Dalam versi Delphi 10 Seattle atau Delphi yang lebih baru, algoritma HMAC juga ada di sistem. Unit kerusakan sehingga OpenSSL tidak diperlukan.
Algoritma HMAC-RSA (ECDSA) menggunakan OpenSSL, jadi jika Anda berencana menggunakan algoritma ini untuk menandatangani token Anda, Anda harus mengunduh dan menggunakan OpenSSL (di server).
Harap diingat bahwa klien tidak harus menghasilkan atau memverifikasi token (menggunakan SHA atau RSA) sehingga di sisi klien tidak perlu untuk openssl DLL.
Jika Anda memerlukan pustaka OpenSSL di server, Anda dapat mengunduh paket langsung ke halaman Proyek GitHub Indy (Perlu diingat untuk selalu memperbarui ke versi terbaru dan untuk mencocokkan Bitness Aplikasi Anda)
Jose adalah standar yang memberikan pendekatan umum untuk penandatanganan dan enkripsi konten apa pun. Jose terdiri dari beberapa RFC:
| Algoritma | Didukung |
|---|---|
exp | ✔️ |
iat | ✔️ |
nbf | ✔️ |
aud | ✔️ |
iss | ✔️ |
jti | ✔️ |
typ | ✔️ |
TJOSEProducer dan TJOSEProducerBuilder (Alias TJOSEProcess ) untuk membangun token ringkas baru dengan banyak opsi TJOSEConsumer dan TJOSEConsumerBuilder yang mudah digunakan untuk memvalidasi token dengan granularitas halus| Algoritma | Didukung |
|---|---|
None | ✔️ Jangan menggunakannya! ? |
HS256 | ✔️ |
HS384 | ✔️ |
HS512 | ✔️ |
RS256 | ✔️ Diperbarui! |
RS384 | ✔️ Diperbarui! |
RS512 | ✔️ Diperbarui! |
ES256 | ✔️ Baru! ? |
ES384 | ✔️ Baru! ? |
ES512 | ✔️ Baru! ? |
ES256K | ✔️ Baru! ? |
NonePerpustakaan ini telah diuji dengan Delphi 12 Athena , Delphi 11 Alexandria , Delphi 10.4 Sydney , Delphi 10.3 Rio , Delphi 10.2 Tokyo tetapi dengan beberapa pekerjaan itu harus dikompilasi dengan DXE6 dan lebih tinggi tetapi saya belum mencoba atau menguji ini, jika Anda berhasil dalam tugas ini saya akan senang membuat cabang karya Anda!
Perpustakaan ini tidak memiliki ketergantungan pada pustaka/unit eksternal.
Unit Delphi digunakan:
Cukup tambahkan jalur sumber "sumber/umum" dan sumber/jose "ke jalur proyek Delphi Anda dan .. Anda baik untuk pergi!
Menggunakan perintah boss install :
$ boss install github.com/paolo-rossi/delphi-jose-jwt Untuk membuat token, cukup buat instance dari kelas TJWT dan atur properti (klaim).
Cara termudah untuk membangun token JWT (representasi kompak) adalah dengan menggunakan antarmuka IJOSEProducer :
uses
JOSE.Producer;
var
LResult: string;
begin
LResult := TJOSEProcess.New
.SetIssuer( ' Delphi JOSE Library ' )
.SetIssuedAt(Now)
.SetExpiration(Now + 1 )
.SetAlgorithm(LAlg)
.SetKey(TJOSEAlgorithmId.HS256)
.Build
.GetCompactToken
;
memoCompact.Lines.Add(LResult);
end ; Cara lain untuk membuat serial, deserialize, memverifikasi token adalah dengan menggunakan kelas utilitas TJOSE :
uses
JOSE.Core.JWT,
JOSE.Core.Builder;
var
LToken: TJWT;
LCompactToken: string;
begin
LToken := TJWT.Create;
try
// Token claims
LToken.Claims.Issuer := ' WiRL REST Library ' ;
LToken.Claims.Subject := ' Paolo Rossi ' ;
LToken.Claims.Expiration := Now + 1 ;
// Signing and Compact format creation
LCompactToken := TJOSE.SHA256CompactToken( ' my_very_long_and_safe_secret_key ' , LToken);
mmoCompact.Lines.Add(LCompactToken);
finally
LToken.Free;
end ; Menggunakan kelas TJWT , TJWS dan TJWK Anda memiliki lebih banyak kendali atas pembuatan token kompak akhir.
var
LToken: TJWT;
LSigner: TJWS;
LKey: TJWK;
LAlg: TJOSEAlgorithmId;
begin
LToken := TJWT.Create;
try
// Set your claims
LToken.Claims.Subject := ' Paolo Rossi ' ;
LToken.Claims.Issuer := ' Delphi JOSE Library ' ;
LToken.Claims.IssuedAt := Now;
LToken.Claims.Expiration := Now + 1 ;
// Choose the signing algorithm
case cbbAlgorithm.ItemIndex of
0 : LAlg := TJOSEAlgorithmId.HS256;
1 : LAlg := TJOSEAlgorithmId.HS384;
2 : LAlg := TJOSEAlgorithmId.HS512;
else LAlg := TJOSEAlgorithmId.HS256;
end ;
// Create your key from any text or TBytes
LKey := TJWK.Create(edtSecret.Text);
try
// Create the signer
LSigner := TJWS.Create(LToken);
try
// With this option you can have keys < algorithm length
LSigner.SkipKeyValidation := True;
// Sign the token!
LSigner.Sign(LKey, LAlg);
memoCompact.Lines.Add( ' Header: ' + LSigner.Header);
memoCompact.Lines.Add( ' Payload: ' + LSigner.Payload);
memoCompact.Lines.Add( ' Signature: ' + LSigner.Signature);
memoCompact.Lines.Add( ' Compact Token: ' + LSigner.CompactToken);
finally
LSigner.Free;
end ;
finally
LKey.Free;
end ;
finally
LToken.Free;
end ;
Membongkar dan memverifikasi token itu sederhana.
Anda harus meneruskan kunci dan format Token Compact ke fungsi kelas TJOSE.Verify
var
LKey: TJWK;
LToken: TJWT;
begin
// Create the key from a text or TBytes
LKey := TJWK.Create( ' my_very_long_and_safe_secret_key ' );
// Unpack and verify the token!
LToken := TJOSE.Verify(LKey, FCompactToken);
if Assigned(LToken) then
begin
try
if LToken.Verified then
mmoJSON.Lines.Add( ' Token signature is verified ' )
else
mmoJSON.Lines.Add( ' Token signature is not verified ' )
finally
LToken.Free;
end ;
end ;
end ; Menggunakan kelas baru TJOSEConsumer sangat mudah untuk memvalidasi klaim token. Objek TJOSEConsumer dibangun dengan kelas utilitas TJOSEConsumerBuilder menggunakan antarmuka FLUENT.
var
LConsumer: IJOSEConsumer;
begin
LConsumer := TJOSEConsumerBuilder.NewConsumer
.SetClaimsClass(TJWTClaims)
// JWS-related validation
.SetVerificationKey(edtConsumerSecret.Text)
.SetSkipVerificationKeyValidation
.SetDisableRequireSignature
// string-based claims validation
.SetExpectedSubject( ' paolo-rossi ' )
.SetExpectedAudience(True, [ ' Paolo ' ])
// Time-related claims validation
.SetRequireIssuedAt
.SetRequireExpirationTime
.SetEvaluationTime(IncSecond(FNow, 26 ))
.SetAllowedClockSkew( 20 , TJOSETimeUnit.Seconds)
.SetMaxFutureValidity( 20 , TJOSETimeUnit.Minutes)
// Build the consumer object
.Build();
try
// Process the token with your rules!
LConsumer.Process(Compact);
except
// (optionally) log the errors
on E: Exception do
memoLog.Lines.Add(E.Message);
end ;