Artikel ini akan memperkenalkan JWT dan cara menggunakan PHP untuk pengesahan permintaan pengguna berasaskan JWT.
mata utama
Evolusi kaedah pengesahan:Pertama sekali, mengapa perbualan tidak begitu baik? Terdapat tiga sebab utama:
Data disimpan pada pelayan dalam teks biasa. Walaupun data tidak biasanya disimpan dalam folder awam, sesiapa yang mempunyai akses pelayan yang mencukupi dapat membaca kandungan fail sesi.
Sekarang, mari mula belajar JWT. Spesifikasi Token Web JSON (RFC 7519) pertama kali dikeluarkan pada 28 Disember 2010, dan kemas kini paling terkini pada Mei 2015.
JWT mempunyai banyak kelebihan atas kekunci API, termasuk:Apa yang kelihatan seperti JWT?
ini adalah contoh JWT:
<code>eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MTY5MjkxMDksImp0aSI6ImFhN2Y4ZDBhOTVjIiwic2NvcGVzIjpbInJlcG8iLCJwdWJsaWNfcmVwbyJdfQ.XCEwpBGvOLma4TCoh36FU7XhUbcskygS81HE1uHLf0E</code>
Pada pandangan pertama, rentetan ini nampaknya hanya sekumpulan aksara rawak yang berkaitan dengan tempoh atau watak -watak DOT. Jadi nampaknya tidak berbeza dengan kunci API. Walau bagaimanapun, jika anda melihat dengan teliti, anda akan melihat bahawa terdapat tiga rentetan berasingan.
Rentetan pertama adalah tajuk JWT. Ia adalah rentetan JSON yang dikodkan URL BASE64. Ia menentukan algoritma penyulitan yang digunakan untuk menghasilkan tandatangan dan jenis token, yang sentiasa ditetapkan kepada JWT. Algoritma boleh simetri atau asimetri .
Algoritma simetri menggunakan kunci tunggal untuk membuat dan mengesahkan token. Kunci ini dikongsi antara pencipta dan pengguna JWT. Pastikan anda hanya memastikan pencipta dan pengguna mengetahui kunci. Jika tidak, sesiapa sahaja boleh membuat token yang sah. Algoritma asimetrik menggunakan kunci peribadi untuk menandatangani token dan menggunakan kunci awam untuk mengesahkan token. Algoritma ini harus digunakan apabila kunci yang dikongsi tidak praktikal atau apabila pihak lain hanya perlu mengesahkan integriti token.
muatan JWT
, awam dan private . Penyata pendaftaran dipratentukan. Anda boleh mencari senarai mereka di RFC JWT. Berikut adalah beberapa kenyataan yang biasa digunakan:
IAT: Tarikh dan Timestamp yang dikeluarkan oleh Token.
tandatangan JWT
tandatangan JWT adalah gabungan tiga perkara:
Ketiga -tiga ini ditandatangani secara digital menggunakan algoritma yang dinyatakan dalam tajuk JWT ( tidak disulitkan ). Jika kita menyahkod contoh di atas, kita akan mendapat rentetan JSON berikut:
header JWT
<code>eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MTY5MjkxMDksImp0aSI6ImFhN2Y4ZDBhOTVjIiwic2NvcGVzIjpbInJlcG8iLCJwdWJsaWNfcmVwbyJdfQ.XCEwpBGvOLma4TCoh36FU7XhUbcskygS81HE1uHLf0E</code>
data JWT
<code>{ "alg": "HS256", "typ": "JWT" }</code>
anda boleh mencuba jwt.io sendiri, di mana anda boleh mencuba pengekodan dan penyahkodan JWT anda sendiri.
Gunakan JWT dalam aplikasi berasaskan PHP
Sekarang anda telah mempelajari apa JWT, sudah tiba masanya untuk belajar cara menggunakannya dalam aplikasi PHP anda. Jangan ragu untuk mengklonkan kod artikel ini, atau ikuti langkah kami sebelum membincangkannya.
Anda boleh mengambil beberapa cara untuk mengintegrasikan JWT, tetapi inilah yang akan kami ambil.
Selain dari halaman log masuk dan logout, semua permintaan untuk permohonan perlu disahkan melalui JWT. Jika pengguna membuat permintaan tanpa JWT, mereka akan diarahkan ke halaman log masuk.
Selepas pengguna mengisi dan mengemukakan borang log masuk, borang akan dikemukakan melalui JavaScript ke endpoint endpoint login.php dalam permohonan kami. Titik akhir kemudian menarik kelayakan (nama pengguna dan kata laluan) dari permintaan dan cek bahawa mereka sah.
Jika sah, ia akan menjana JWT dan menghantarnya kembali kepada pelanggan. Apabila pelanggan menerima JWT, ia menyimpan JWT dan menggunakannya untuk setiap permintaan masa depan untuk permohonan itu.
Untuk senario mudah, pengguna hanya boleh meminta satu sumber - sumber fail php yang betul. Ia tidak berbuat banyak, ia hanya mengembalikan rentetan yang mengandungi cap waktu semasa pada masa permintaan.
Terdapat beberapa cara untuk menggunakan JWT semasa membuat permintaan. Dalam permohonan kami, JWT akan dihantar dalam tajuk kebenaran pembawa.
Jika anda tidak biasa dengan kebenaran pembawa, ia adalah satu bentuk pengesahan HTTP di mana token (seperti JWT) dihantar dalam tajuk permintaan. Pelayan boleh menyemak token dan menentukan sama ada akses "pemegang" ke token harus diberikan.
Ini adalah contoh tajuk:
<code>{ "iat": 1416929109, "jti": "aa7f8d0a95c", "scopes": [ "repo", "public_repo" ] }</code>
Untuk setiap permintaan permohonan kami diterima, PHP akan cuba mengekstrak token dari tajuk pembawa. Jika ia wujud, ia disahkan. Jika sah, pengguna akan melihat tindak balas biasa terhadap permintaan tersebut. Walau bagaimanapun, jika JWT tidak sah, pengguna tidak dibenarkan mengakses sumber.
Sila ambil perhatian bahawa JWT tidak dimaksudkan untuk menggantikan kuki sesi.
PrasyaratDalam direktori root projek, jalankan pemasangan komposer. Ini akan memperkenalkan Firebase PHP-JWT, perpustakaan pihak ketiga yang memudahkan operasi JWT, dan Laminas-Config untuk memudahkan akses kepada data konfigurasi dalam aplikasi.
borang log masuk
<code>eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MTY5MjkxMDksImp0aSI6ImFhN2Y4ZDBhOTVjIiwic2NvcGVzIjpbInJlcG8iLCJwdWJsaWNfcmVwbyJdfQ.XCEwpBGvOLma4TCoh36FU7XhUbcskygS81HE1uHLf0E</code>
Selepas menerima penyerahan borang, kelayakan akan disahkan terhadap pangkalan data atau beberapa kedai data lain. Untuk tujuan contoh ini, kami akan menganggap mereka sah dan menetapkan $ hasvalidcredentials kepada benar.
<code>{ "alg": "HS256", "typ": "JWT" }</code>
Seterusnya, kami memulakan satu set pembolehubah untuk menjana JWT. Ingatlah bahawa sejak JWT boleh diperiksa pada pelanggan, jangan sertakan maklumat sensitif di dalamnya. Satu lagi perkara yang patut ditunjukkan ialah $ SecretKey tidak diasaskan seperti ini. Anda mungkin menetapkannya di persekitaran anda dan mengeluarkannya, menggunakan perpustakaan seperti phpDotenv, atau tetapkannya dalam fail konfigurasi. Dalam kes ini, saya mengelakkan melakukan ini kerana saya ingin memberi tumpuan kepada kod JWT.
Jangan bocor atau simpan di bawah kawalan versi!
Selepas menyediakan data muatan, kami menggunakan kaedah pengekodan statik PHP-JWT untuk membuat JWT.
<code>{ "iat": 1416929109, "jti": "aa7f8d0a95c", "scopes": [ "repo", "public_repo" ] }</code>
Kaedah ini:
tukar array ke json
Maklumat muatan
menggunakan jwt
<code>Authorization: Bearer ab0dde18155a43ee83edba4a4542b973</code>
Sekarang pelanggan mempunyai token, anda boleh menyimpannya menggunakan JavaScript atau mana -mana mekanisme yang anda suka. Berikut adalah contoh cara beroperasi menggunakan JavaScript asli. Dalam index.html, selepas borang itu berjaya diserahkan, JWT yang diterima akan disimpan dalam ingatan, borang log masuk akan tersembunyi, dan butang yang meminta cap waktu akan dipaparkan:
menggunakan jwt
<?php declare(strict_types=1); use Firebase\JWT\JWT; require_once('../vendor/autoload.php');
Apabila kita mengklik butang, permintaan yang serupa dengan yang berikut akan dikeluarkan:
<?php // 从请求中提取凭据 if ($hasValidCredentials) {
Dengan mengandaikan bahawa JWT adalah sah, kita akan melihat sumber dan respons akan ditulis kepada konsol selepas itu.
$secretKey = 'bGS6lzFqvvSQ8ALbOxatm7/Vk7mLQyzqaS34Q4oR1ew='; $issuedAt = new DateTimeImmutable(); $expire = $issuedAt->modify('+6 minutes')->getTimestamp(); // 添加60秒 $serverName = "your.domain.name"; $username = "username"; // 从过滤后的POST数据中检索 $data = [ 'iat' => $issuedAt->getTimestamp(), // 颁发时间:生成令牌的时间 'iss' => $serverName, // 颁发者 'nbf' => $issuedAt->getTimestamp(), // 不早于 'exp' => $expire, // 过期 'userName' => $username, // 用户名 ];
Sahkan JWT
Kod kemudian akan cuba mengekstrak token dari tajuk pembawa. Saya telah melakukan ini menggunakan preg_match. Jika anda tidak biasa dengan fungsi ini, ia akan melakukan padanan ekspresi biasa pada rentetan.
<?php // 将数组编码为JWT字符串。 echo JWT::encode( $data, $secretKey, 'HS512' ); }
Regex yang saya gunakan di sini akan cuba mengekstrak token dari pengepala pembawa dan membuang segala yang lain. Jika tidak dijumpai, permintaan ralat HTTP 400 dikembalikan:
Perhatikan bahawa secara lalai, Apache tidak lulus header HTTP_Authorization ke PHP. Alasan di sebalik itu ialah:
const store = {}; const loginButton = document.querySelector('#frmLogin'); const btnGetResource = document.querySelector('#btnGetResource'); const form = document.forms[0]; // 将jwt插入到store对象中 store.setJWT = function (data) { this.JWT = data; }; loginButton.addEventListener('submit', async (e) => { e.preventDefault(); const res = await fetch('/authenticate.php', { method: 'POST', headers: { 'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8' }, body: JSON.stringify({ username: form.inputEmail.value, password: form.inputPassword.value }) }); if (res.status >= 200 && res.status < 300) { const jwt = await res.text(); store.setJWT(jwt); frmLogin.style.display = 'none'; btnGetResource.style.display = 'block'; } else { // 处理错误 console.log(res.status, res.statusText); } });
Header Kebenaran Asas hanya selamat apabila sambungan anda selesai melalui HTTPS, kerana jika tidak, kelayakan akan dihantar melalui rangkaian dalam plaintext yang dikodkan (tidak disulitkan), yang merupakan isu keselamatan yang besar.
Saya memahami sepenuhnya logik keputusan ini. Walau bagaimanapun, untuk mengelakkan banyak kekeliruan, tambahkan yang berikut ke konfigurasi Apache anda. Kod itu akan berfungsi seperti yang diharapkan. Jika anda menggunakan nginx, kod itu harus berfungsi seperti yang diharapkan:
<code>eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MTY5MjkxMDksImp0aSI6ImFhN2Y4ZDBhOTVjIiwic2NvcGVzIjpbInJlcG8iLCJwdWJsaWNfcmVwbyJdfQ.XCEwpBGvOLma4TCoh36FU7XhUbcskygS81HE1uHLf0E</code>
Seterusnya, kami cuba mengekstrak JWT yang sepadan, yang akan menjadi elemen kedua pembolehubah $ perlawanan. Sekiranya tidak tersedia, tiada JWT diekstrak dan permintaan ralat HTTP 400 dikembalikan:
<code>{ "alg": "HS256", "typ": "JWT" }</code>
Jika kita mencapai titik ini, JWT telah diekstrak, jadi kita pergi ke fasa penyahkodan dan pengesahan. Untuk melakukan ini, kami memerlukan kunci kami sekali lagi, yang akan diekstrak dari konfigurasi persekitaran atau permohonan. Kemudian, kami menggunakan kaedah decode statik PHP-JWT untuk menyampaikannya ke JWT, kunci dan satu set algoritma yang digunakan untuk menyahkod JWT. Jika ia dapat berjaya dimulakan, kami akan cuba mengesahkannya. Contoh saya di sini adalah sangat mudah kerana ia hanya menggunakan penerbit, tidak lebih awal daripada, dan tamat tempoh tamat. Dalam aplikasi sebenar, anda juga boleh menggunakan banyak kenyataan lain.
Jika token tidak sah, seperti token telah tamat, pengguna akan menerima header HTTP 401 yang tidak dibenarkan dan skrip akan keluar.
<code>{ "iat": 1416929109, "jti": "aa7f8d0a95c", "scopes": [ "repo", "public_repo" ] }</code>
Jika proses penyahkodan dan pengesahan gagal, mungkin:
Bilangan segmen yang disediakan tidak sepadan dengan tiga segmen standard yang diterangkan di atas.
Jika proses penyahkodan dan pengesahan berjaya, pengguna akan dibenarkan mengeluarkan permintaan dan akan menerima respons yang sepadan.
Ringkasan
Ini adalah pengenalan cepat kepada Token Web JSON (atau JWT) dan cara menggunakannya dalam aplikasi berasaskan PHP. Dari sini anda boleh cuba melaksanakan JWT dalam API seterusnya, mungkin cuba beberapa algoritma tandatangan lain yang menggunakan kekunci asimetrik seperti RS256, atau mengintegrasikannya ke dalam pelayan pengesahan OAuth2 yang sedia ada untuk digunakan sebagai kunci API.
Jika anda mempunyai sebarang komen atau soalan, sila hubungi kami melalui Twitter.
Soalan Lazim Menggunakan JWT untuk Kebenaran PHP
Anda sememangnya boleh menggunakan JWT dalam PHP untuk menubuhkan mekanisme pengesahan dan kebenaran dalam aplikasi web anda. Untuk memulakan, anda perlu menggunakan komposer untuk memasang perpustakaan PHP JWT, seperti "Firebase/PHP-JWT" atau "LCOBUCCI/JWT". Perpustakaan ini menyediakan alat yang diperlukan untuk membuat, pengekodan, penyahkodan, dan mengesahkan JWT.
Untuk membuat JWT, anda boleh menggunakan perpustakaan untuk membina token yang mengandungi kenyataan seperti penerbit, penonton, masa tamat tempoh, dan banyak lagi. Setelah dibuat, anda boleh menandatangani token dengan kunci. Apabila menerima JWT, anda boleh menggunakan perpustakaan untuk menyahkod dan mengesahkannya untuk memastikan keasliannya. Jika token itu sah dan disahkan, anda boleh mengakses pengisytiharannya untuk menentukan identiti dan keizinan pengguna, yang membolehkan anda melaksanakan pengesahan dan kebenaran yang selamat dalam aplikasi PHP anda.
Melindungi kunci anda dan mengikuti amalan terbaik keselamatan apabila menggunakan JWT adalah penting untuk mengelakkan akses yang tidak dibenarkan kepada sumber aplikasi. JWT (JSON Web Token) Pengesahan dalam PHP adalah kaedah yang digunakan secara meluas untuk melaksanakan pengesahan pengguna dan kebenaran dalam aplikasi web. Ia berdasarkan pengesahan token dan membolehkan pengesahan pengguna yang selamat dan tidak bertauliah. Inilah cara pengesahan JWT berfungsi dalam PHP:
Pertama, semasa pengesahan pengguna atau log masuk, pelayan menjana JWT, token yang padat, yang mengandungi maklumat (tuntutan) yang berkaitan dengan pengguna, seperti ID pengguna, nama pengguna, dan peranan. Pengisytiharan ini biasanya data JSON. Pelayan kemudian menandatangani token ini dengan kunci untuk memastikan integriti dan keasliannya.
Kedua, selepas pengesahan yang berjaya, pelayan menghantar JWT kembali kepada pelanggan, yang biasanya disimpan di lokasi yang selamat seperti kuki HTTP atau storan tempatan. Token ini berfungsi sebagai bukti pengesahan.
Akhirnya, untuk permintaan berikutnya kepada sumber yang dilindungi di pelayan, klien menambahkan JWT ke tajuk permintaan, biasanya menggunakan tajuk "Kebenaran" dengan skim "Pembawa". Selepas menerima JWT, pelayan menggunakan kunci yang sama yang digunakan semasa penciptaan token untuk mengesahkan tandatangannya. Di samping itu, ia memeriksa sama ada token tidak tamat tempoh dan mengandungi perisytiharan yang sah. Selepas pengesahan yang berjaya, ia mengekstrak maklumat pengguna dari Perisytiharan Token dan melaksanakan Logik Kebenaran untuk memastikan pengguna mempunyai kebenaran yang diperlukan untuk mengakses sumber yang diminta. Pendekatan ini membolehkan pengesahan yang selamat dan tidak bertauliah dalam aplikasi PHP tanpa penyimpanan sesi pelayan.
Walaupun pengesahan JWT di PHP memberikan banyak faedah seperti skalabilitas dan ketiadaan, amalan terbaik untuk melindungi kunci dan mengadopsi pengurusan token adalah penting untuk mengekalkan keselamatan permohonan anda. Menggunakan perpustakaan PHP JWT yang ditubuhkan dapat memudahkan pemprosesan token dan meningkatkan keselamatan. Alternatif kepada JWT (JSON Web Tokens) untuk pengesahan dan kebenaran dalam PHP adalah pengesahan berasaskan sesi. Dalam pengesahan berasaskan sesi, pelayan mengekalkan satu sesi untuk setiap pengguna yang disahkan. Apabila pengguna log masuk, pengecam sesi unik dibuat (biasanya disimpan sebagai cookie sesi pada pelayar pelanggan). Pengenalpastian ini digunakan untuk mengaitkan pengguna dengan data sesi pelayan, termasuk maklumat yang berkaitan dengan pengguna, seperti ID pengguna, nama pengguna, dan keizinan.
Pengesahan berasaskan sesi menyediakan kesederhanaan dan kemudahan pelaksanaan, menjadikannya sesuai untuk pelbagai aplikasi web, terutama jika anda tidak memerlukan keupayaan stateless dan berskala JWT. Ia secara semula jadi, yang boleh menjadi berfaedah apabila anda perlu menguruskan data khusus pengguna (seperti kandungan keranjang belanja atau keutamaan pengguna) semasa sesi pengguna.
Walau bagaimanapun, terdapat beberapa perkara yang perlu dipertimbangkan semasa menggunakan pengesahan berasaskan sesi. Ia mungkin tidak boleh digunakan untuk arsitektur berasaskan diedarkan atau microservice yang memerlukan pengesahan tanpa stat. Di samping itu, menguruskan sesi pengguna boleh meningkatkan beban pelayan, terutamanya dalam aplikasi dengan pangkalan pengguna yang lebih besar. Akhirnya, memilih JWT dan pengesahan berasaskan sesi dalam PHP sepadan dengan keperluan khusus dan pertimbangan reka bentuk aplikasi untuk memastikan mekanisme pengesahan yang selamat dan berkesan memenuhi keperluan anda. Melindungi API PHP dengan JWT (Token Web JSON) melibatkan proses pelbagai langkah yang menggabungkan pengesahan dan kebenaran. Pertama, pilih perpustakaan PHP JWT yang sesuai (seperti "Firebase/PHP-JWT" atau "LCOBUCCI/JWT") untuk mengendalikan operasi yang berkaitan dengan token dan menggunakan komposer untuk menguruskan kebergantungan.
Untuk pengesahan, anda perlu melaksanakan sistem pengesahan pengguna dalam aplikasi PHP anda. Sistem ini mengesahkan kelayakan pengguna terhadap pangkalan data atau penyedia pengesahan anda. Selepas pengesahan yang berjaya, anda akan menghasilkan token JWT yang mengandungi tuntutan yang berkaitan dengan pengguna seperti ID pengguna, nama pengguna, dan peranan. Pastikan untuk menetapkan masa tamat tempoh untuk mengawal kesahihan token dan kemudian tandatangan token dengan kunci. Token yang ditandatangani ini dihantar kembali kepada pelanggan sebagai sebahagian daripada tindak balas pengesahan.
Pelanggan menyimpan JWT yang diterima dengan selamat, biasanya dalam kuki HTTP atau storan tempatan. Untuk permintaan API berikutnya, pelanggan akan memasukkan JWT dalam tajuk permintaan sebagai tajuk "Kebenaran" dengan skim "Pembawa". Dalam API PHP anda, anda boleh mengesahkan JWT yang masuk dengan mengesahkan tandatangannya menggunakan kunci yang sama yang digunakan semasa membuat token. Di samping itu, anda menyemak bahawa token tidak tamat tempoh dan mengandungi perisytiharan yang sah. Selepas pengesahan yang berjaya, anda mengekstrak maklumat pengguna dari Deklarasi Token dan melaksanakan Logik Kebenaran untuk memastikan pengguna mempunyai kebenaran yang diperlukan untuk mengakses sumber yang diminta.
Menjaga aman utama adalah penting kerana ia adalah penting untuk menandatangani dan mengesahkan token. Mana -mana kebocoran kunci ini boleh membawa kepada kelemahan keselamatan yang serius. Bolehkah kita menggunakan JWT dalam PHP?
Apakah Pengesahan JWT dalam PHP?
Apakah alternatif kepada JWT dalam PHP?
Bagaimana untuk melindungi API PHP menggunakan JWT?
Atas ialah kandungan terperinci Kebenaran PHP dengan JWT (JSON Web Tokens). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!