{"alg":"HS256","typ":"JWT"}{"sub":"1234567890","name":"Juan dela Cruz","role":"member","iat":1756400000,"exp":1756486400}No secret was needed to produce either of those. They were read straight out of the token above.
Ang JWT ay pinipirmahan, hindi ini-encrypt. Ang isang pangungusap na iyon ang dahilan kung bakit ipinapakita ng pahinang ito ang na-decode na payload katabi mismo ng token.
Ang gitnang bahagi ng JWT ay base64url — isang encoding, na kayang baligtarin ninuman, at hindi cipher, na nangangailangan ng susi. Kayang basahin ng bawat may hawak ng token ang bawat claim doon. Iba at mas makitid ang ginagawa ng pirma: pinapatunayan nitong hindi binago ang token mula nang pirmahan mo. Wala itong itinatago.
Naglalagay ang mga tao ng password, numero ng pagkakakilanlan at internal na flag sa payload dahil mukhang naka-encrypt ang token — mahaba at malabong string na walang kahulugan sa mata. Ang generator na ang string lamang na iyon ang ipinapakita ay tumutulong sa mambabasang maniwala sa mali, kaya dini-decode ito pabalik ng isang ito para sa iyo at tinutukoy ang alinmang claim na mukhang lihim ang key.
Walang "none" na algorithm dito at hindi magkakaroon kailanman. Kayang pekein ninuman ang hindi ligtas na token, at ang server na tumatanggap nito ay walang anumang authentication. Ang header na sinusubukang itakda ang algorithm ay tinatanggihan sa halip na tahimik na palitan — dapat mong malaman na hindi ka makakagawa ng ganoon, hindi maniwalang nakagawa ka.
Segundo ang timestamp, hindi millisecond. Ang exp, iat at nbf ay segundo mula sa epoch; millisecond ang Date.now(). Ipasa ang isa nang diretso at mag-e-expire ang token mo pagkalipas ng mga limampung libong taon, at walang anumang magrereklamo kahit saan.
Hindi, at ito ang maling pagkakaunawang pinagtuunan ng buong pahina. Ang payload ay base64url — encoding, hindi cipher. Kayang basahin ninumang may hawak ng token ang bawat claim dito nang walang lihim, kaya ipinapakita ng pahinang ito ang na-decode na payload sa tabi ng token sa halip na itago ito. Pinatutunayan ng lagda na hindi binago ang token; wala itong itinatago.
Anumang hindi mo ipi-print sa postcard. Mga password, national ID number, detalye ng card, panloob na flag na ayaw mong makita ng customer. Maglagay ng reference sa token — isang user id — at itago ang halaga sa server kung saan ito nararapat. Pinapangalanan ng pahinang ito ang anumang claim na mukhang lihim ang key, pero ang pangalan lang ang nakikita nito, hindi ang ibig mong sabihin.
Dahil kayang pekein ninuman ang JWT na walang seguridad, at ang server na tumatanggap nito ay walang anumang authentication. Ito ang pinakamadalas pagsamantalahang bahagi ng espesipikasyon. Hindi gagawa nito ang generator na ito, at tinatanggihan nito ang header na nagtatangkang magtakda ng algorithm sa halip na tahimik itong palitan — dapat mong malaman na hindi mo kaya, hindi maniwalang nagawa mo.
HS256 maliban kung may kailangang iba sa panig mo. Ang tatlo ay HMAC sa ibinahaging lihim at maayos silang tatlo; gumagamit ang HS384 at HS512 ng mas malapad na hash at gumagawa ng mas mahabang lagda, na nagpapalaki sa token nang hindi ginagawang makabuluhang mas mahirap hulaan ang maayos na piniling lihim. Ang mahinang bahagi ng JWT na nilagdaan ng HMAC ay halos laging ang lihim, hindi ang hash — kaya mas malaki ang naibibigay ng mas mahabang lihim kaysa sa mas mahabang pangalan ng algorithm.
Kailangan ng RS256 at ES256 ang paghawak ng RSA o elliptic-curve na key, at mas malaking sakop iyon kaysa sa dapat dalhin ng token generator, at mas masahol ang kalahating pamamaraan ng lagda kaysa wala. Ang tatlong inaalok dito ay ang buong pamilya ng HMAC, ginawa mula sa espesipikasyon nang walang dependency — sinusuri ang mga hash laban sa inilathalang FIPS 180-4 at RFC 4231 na test vectors.
Milliseconds ang ginamit mo. Ang mga timestamp ng JWT — exp, iat at nbf — ay segundo mula sa epoch, at nagbibigay ng milliseconds ang Date.now(), kaya ang halagang ipinasa nang tuwiran ay isang libong beses na masyadong malaki. Walang library na tumatanggi rito at walang mukhang mali, kaya minamarkahan ng pahinang ito ang timestamp na masyadong malaki para maging kapani-paniwalang bilang ng segundo. Hatiin sa 1000.
Hindi bababa sa 32 random na bytes. Ang umaatakeng nakakuha ng isang token ay puwedeng sumubok ng hula laban dito nang offline, kasingbilis ng kaya ng hardware nila at hindi man lang hinahawakan ang server mo — kaya hindi sapat ang madaling tandaang passphrase. Gumawa ng isa sa secret key page sa halip na mag-imbento.
Hindi, nilalagdaan lang nito. Sulit ding sabihin na ang pag-verify ng token ay pagsusuri ng lagda gamit ang lihim at saka pagsusuri ng mga claim — ang expiry, ang issuer, ang audience. Ang pag-decode ng token at pagbasa ng claims nito nang hindi sinusuri ang lagda ay hindi authentication, gaano man kakumbinsi ang itsura ng payload.
Dalawa sa tatlo ay payak na tekstong nagbabalatkayo. Ang pangatlo lamang ang nangangailangan ng lihim.
Integridad, hindi pagiging lihim. Kung kailangan mo ang pangalawa, i-encrypt ang halaga bago ito ipasok — o mas mabuti pa, itago ito sa server at maglagay ng sanggunian sa token.
Nilagdaan sa browser mo; hindi kailanman ipinapadala o iniimbak ang lihim. Ang JWT ay nilalagdaan, hindi ini-encrypt — ituring na pampubliko ang lahat ng nasa payload. Tool ito sa pagbuo, hindi pagsusuri sa seguridad. Walang ipinapadala sa mga server namin ang tina-type mo rito — sa browser mo tumatakbo nang buo ang pagkuwenta.