Maison >développement back-end >tutoriel php >Autorisation PHP avec JWT (jetons Web JSON)
L'authentification de l'application utilisée pour s'appuyer uniquement sur des informations d'identification telles que le nom d'utilisateur / boîte aux lettres et le mot de passe, et la session a été utilisée pour maintenir l'état de l'utilisateur jusqu'à ce que l'utilisateur se connecte. Après cela, nous avons commencé à utiliser l'API d'authentification. Récemment, les jetons Web JSON (JWT) sont de plus en plus utilisés pour authentifier les demandes de serveur.
Cet article présentera ce qu'est JWT et comment utiliser PHP pour l'authentification de la demande utilisateur basée sur JWT.
Points clés
jwt et session
Tout d'abord, pourquoi la conversation n'est-elle pas si bonne? Il y a trois raisons principales:
jwt
Maintenant, commençons à apprendre JWT. La spécification du jeton Web JSON (RFC 7519) a été publiée pour la première fois le 28 décembre 2010, et la dernière mise à jour a eu lieu en mai 2015.
JWT présente de nombreux avantages par rapport aux clés d'API, notamment:
À quoi ressemble JWT?
Ceci est un exemple JWT:
<code>eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MTY5MjkxMDksImp0aSI6ImFhN2Y4ZDBhOTVjIiwic2NvcGVzIjpbInJlcG8iLCJwdWJsaWNfcmVwbyJdfQ.XCEwpBGvOLma4TCoh36FU7XhUbcskygS81HE1uHLf0E</code>
À première vue, cette chaîne semble être juste un groupe aléatoire de caractères liés à des périodes ou à des caractères DOT. Il ne semble donc pas être différent de la clé API. Cependant, si vous regardez attentivement, vous verrez qu'il y a trois chaînes distinctes.
La première chaîne est l'en-tête JWT. Il s'agit d'une chaîne JSON codée par URL Base64. Il spécifie l'algorithme de chiffrement utilisé pour générer la signature et le type de jeton, qui est toujours défini sur JWT. L'algorithme peut être symétrique ou asymétrique .
L'algorithme symétrique utilise une seule clé pour créer et vérifier les jetons. Cette clé est partagée entre le créateur et le consommateur du JWT. Assurez-vous de vous assurer que seul le créateur et le consommateur connaissent la clé. Sinon, n'importe qui peut créer un jeton valide. L'algorithme asymétrique utilise une clé privée pour signer le jeton et utilise une clé publique pour vérifier le jeton. Ces algorithmes doivent être utilisés lorsque la clé partagée n'est pas pratique ou lorsque d'autres parties n'ont besoin que de vérifier l'intégrité du jeton.
la charge utile de JWT
, public et privé . L'instruction d'enregistrement est prédéfinie. Vous pouvez en trouver une liste dans la RFC de JWT. Voici quelques déclarations couramment utilisées:
iat: date et horodatage émises par le jeton.
Signature de JWT
La signature de JWT est une combinaison de trois choses:
Ces trois sont signés numériquement en utilisant l'algorithme spécifié dans l'en-tête JWT ( non crypté ). Si nous décodons l'exemple ci-dessus, nous obtiendrons la chaîne JSON suivante:
L'en-tête de JWT
<code>eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MTY5MjkxMDksImp0aSI6ImFhN2Y4ZDBhOTVjIiwic2NvcGVzIjpbInJlcG8iLCJwdWJsaWNfcmVwbyJdfQ.XCEwpBGvOLma4TCoh36FU7XhUbcskygS81HE1uHLf0E</code>
Données de JWT
<code>{ "alg": "HS256", "typ": "JWT" }</code>
Vous pouvez essayer JWT.io vous-même, où vous pouvez essayer de coder et de décoder votre propre JWT.
Utilisez JWT dans les applications basées sur PHP
Maintenant que vous avez appris ce qu'est JWT, il est temps d'apprendre à les utiliser dans votre application PHP. N'hésitez pas à cloner le code de cet article, ou suivez nos étapes avant de y plonger.
Vous pouvez prendre plusieurs façons d'intégrer JWT, mais voici ceux que nous prendrons.
En dehors des pages de connexion et de déconnexion, toutes les demandes de l'application doivent être authentifiées via JWT. Si l'utilisateur fait une demande sans JWT, il sera redirigé vers la page de connexion.
Une fois que l'utilisateur a rempli et soumis le formulaire de connexion, le formulaire sera soumis via JavaScript au point de connexion Authenticiate.php dans notre application. Le point de terminaison tire ensuite les informations d'identification (nom d'utilisateur et mot de passe) à partir de la demande et vérifie qu'ils sont valides.
s'il est valide, il générera un JWT et le renvoie au client. Lorsque le client reçoit le JWT, il stocke le JWT et l'utilise pour chaque demande future à l'application.
Pour un scénario simple, l'utilisateur ne peut demander qu'une seule ressource - un fichier PHP correctement nommé.php. Il ne fait pas grand-chose, il renvoie simplement une chaîne contenant l'horodatage actuel au moment de la demande.
Il existe plusieurs façons d'utiliser JWT lors de la demande. Dans notre candidature, le JWT sera envoyé dans l'en-tête d'autorisation du porteur.
Si vous n'êtes pas familier avec l'autorisation du porteur, c'est une forme d'authentification HTTP où un jeton (tel que JWT) est envoyé dans l'en-tête de demande. Le serveur peut vérifier le jeton et déterminer si l'accès "titulaire" au jeton doit être accordé.
Ceci est un exemple d'un en-tête:
<code>{ "iat": 1416929109, "jti": "aa7f8d0a95c", "scopes": [ "repo", "public_repo" ] }</code>
Pour chaque demande que notre application reçoit, PHP essaiera d'extraire le jeton de l'en-tête du porteur. S'il existe, il est vérifié. S'il est valide, l'utilisateur verra une réponse normale à la demande. Cependant, si le JWT n'est pas valide, l'utilisateur n'est pas autorisé à accéder à la ressource.
Veuillez noter que JWT n'est pas destiné à remplacer les cookies de session.
PrérequisDans le répertoire racine du projet, exécutez l'installation du compositeur. Cela introduira Firebase PHP-JWT, une bibliothèque tierce qui simplifie les opérations JWT et les laminas-config pour simplifier l'accès aux données de configuration dans les applications.
Formulaire de connexion
<code>eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MTY5MjkxMDksImp0aSI6ImFhN2Y4ZDBhOTVjIiwic2NvcGVzIjpbInJlcG8iLCJwdWJsaWNfcmVwbyJdfQ.XCEwpBGvOLma4TCoh36FU7XhUbcskygS81HE1uHLf0E</code>
Après avoir reçu la soumission du formulaire, les informations d'identification seront vérifiées par rapport à la base de données ou à un autre magasin de données. Aux fins de cet exemple, nous supposerons qu'ils sont valides et définiront $ HasvalidCredentials à True.
<code>{ "alg": "HS256", "typ": "JWT" }</code>
Ensuite, nous initialisons un ensemble de variables pour générer JWT. N'oubliez pas que puisque JWT peut être vérifié sur le client, n'incluez aucune information sensible. Une autre chose qui mérite d'être soulignée est que $ Secretkey n'est pas initialisé comme ça. Vous pouvez le définir dans votre environnement et l'extraire, utiliser des bibliothèques comme PhpDotenV ou le définir dans un fichier de configuration. Dans ce cas, j'évite de le faire parce que je veux me concentrer sur le code JWT.
Ne le divulguez pas ou ne le stockez pas sous contrôle de version!
Après avoir préparé les données de la charge utile, nous utilisons ensuite la méthode de code statique de PHP-JWT pour créer le JWT.
<code>{ "iat": 1416929109, "jti": "aa7f8d0a95c", "scopes": [ "repo", "public_repo" ] }</code>
Cette méthode:
Convertir le tableau en JSON
Informations sur la charge utile
en utilisant jwt
<code>Authorization: Bearer ab0dde18155a43ee83edba4a4542b973</code>
Maintenant que le client a le jeton, vous pouvez le stocker à l'aide de JavaScript ou de tout mécanisme que vous aimez. Voici un exemple de la façon de fonctionner à l'aide de JavaScript natif. Dans index.html, une fois le formulaire soumis avec succès, le JWT reçu sera stocké en mémoire, le formulaire de connexion sera masqué et un bouton demandant l'horodatage sera affiché:
en utilisant jwt
<code class="language-php"><?php declare(strict_types=1); use Firebase\JWT\JWT; require_once('../vendor/autoload.php');</code>
Lorsque nous cliquons sur le bouton, une demande similaire à ce qui suit sera émise:
<code class="language-php"><?php // 从请求中提取凭据 if ($hasValidCredentials) {</code>
En supposant que le JWT est valide, nous verrons la ressource et la réponse sera écrite à la console après cela.
<code class="language-php">$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, // 用户名 ];</code>
Vérifiez JWT
Le code essaiera ensuite d'extraire le jeton de l'en-tête du porteur. Je l'ai fait en utilisant preg_match. Si vous n'êtes pas familier avec la fonction, il effectuera une correspondance d'expression régulière sur la chaîne.
<code class="language-php"><?php // 将数组编码为JWT字符串。 echo JWT::encode( $data, $secretKey, 'HS512' ); }</code>
Le regex que j'utilise ici essaiera d'extraire le jeton de l'en-tête du porte-toile et de vider tout le reste. Si cela n'est pas trouvé, une demande d'erreur HTTP 400 est renvoyée:
Notez que par défaut, Apache ne transmet pas l'en-tête HTTP_Authorisation vers PHP. La raison derrière cela est:
<code class="language-javascript">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); } });</code>
L'en-tête d'autorisation de base n'est sécurisé que lorsque votre connexion est terminée via HTTPS, car sinon les informations d'identification seront envoyées sur le réseau en texte clair codé (non crypté), ce qui est un énorme problème de sécurité.
Je comprends parfaitement la logique de cette décision. Cependant, pour éviter beaucoup de confusion, ajoutez ce qui suit à votre configuration Apache. Le code fonctionnera alors comme prévu. Si vous utilisez nginx, le code doit fonctionner comme prévu:
<code>eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MTY5MjkxMDksImp0aSI6ImFhN2Y4ZDBhOTVjIiwic2NvcGVzIjpbInJlcG8iLCJwdWJsaWNfcmVwbyJdfQ.XCEwpBGvOLma4TCoh36FU7XhUbcskygS81HE1uHLf0E</code>
Ensuite, nous essayons d'extraire le JWT correspondant, qui sera dans le deuxième élément de la variable $ correspond. Si indisponible, aucun JWT n'est extrait et une demande d'erreur HTTP 400 n'est renvoyée:
<code>{ "alg": "HS256", "typ": "JWT" }</code>
Si nous atteignons ce point, le JWT a été extrait, nous allons donc à la phase de décodage et de vérification. Pour ce faire, nous avons à nouveau besoin de notre clé, qui sera extraite de la configuration de l'environnement ou de l'application. Ensuite, nous utilisons la méthode de décodage statique de PHP-JWT pour la transmettre au JWT, la clé et un ensemble d'algorithmes utilisés pour décoder le JWT. S'il peut être décodé avec succès, nous essaierons de le vérifier. Mon exemple ici est très simple car il n'utilise que l'émetteur, pas plus tôt, et les horodatages expirés. Dans une application réelle, vous pouvez également utiliser de nombreuses autres déclarations.
Si le jeton n'est pas valide, comme le jeton a expiré, l'utilisateur recevra l'en-tête non autorisé HTTP 401 et le script sortira.
<code>{ "iat": 1416929109, "jti": "aa7f8d0a95c", "scopes": [ "repo", "public_repo" ] }</code>
Si le processus de décodage et de vérification échoue, cela peut être:
Le nombre de segments fournis ne correspond pas aux trois segments standard décrits ci-dessus.
Si le processus de décodage et de vérification est réussi, l'utilisateur sera autorisé à émettre une demande et recevra une réponse correspondante.
Résumé
Il s'agit d'une introduction rapide aux jetons Web JSON (ou JWT) et comment les utiliser dans des applications basées sur PHP. De là, vous pouvez essayer d'implémenter JWT dans l'API suivante, peut-être essayer un autre algorithme de signature qui utilise des clés asymétriques comme RS256, ou l'intégrer dans un serveur d'authentification OAuth2 existant pour utiliser comme clé API.
Si vous avez des commentaires ou des questions, n'hésitez pas à nous contacter via Twitter.
FAQs sur l'utilisation de JWT pour l'autorisation PHP
Vous pouvez en effet utiliser JWT dans PHP pour établir des mécanismes d'authentification et d'autorisation dans votre application Web. Pour commencer, vous devez utiliser Composer pour installer la bibliothèque PHP JWT, telle que "Firebase / PHP-JWT" ou "LcoBucci / JWT". Ces bibliothèques fournissent les outils nécessaires pour créer, coder, décoder et valider les JWT.
Pour créer un JWT, vous pouvez utiliser la bibliothèque pour construire un jeton qui contient des déclarations telles que l'émetteur, le public, le temps d'expiration, etc. Une fois créé, vous pouvez signer le jeton avec la clé. Lorsque vous recevez un JWT, vous pouvez utiliser la bibliothèque pour le décoder et la vérifier pour assurer son authenticité. Si le jeton est valide et vérifié, vous pouvez accéder à sa déclaration pour déterminer l'identité et les autorisations de l'utilisateur, vous permettant d'implémenter l'authentification et l'autorisation sécurisées dans votre application PHP.
Protéger vos clés et suivre les meilleures pratiques de sécurité lors de l'utilisation de JWT est essentiel pour éviter un accès non autorisé aux ressources d'application. JWT (token Web JSON) L'authentification dans PHP est une méthode largement utilisée pour implémenter l'authentification et l'autorisation des utilisateurs dans les applications Web. Il est basé sur l'authentification des jetons et permet une authentification utilisateur sécurisée et sans état. Voici comment fonctionne l'authentification JWT dans PHP:
Tout d'abord, lors de l'authentification ou de la connexion de l'utilisateur, le serveur génère un JWT, un jeton compact et autonome contenant des informations (revendications) liées à l'utilisateur, telles que l'ID utilisateur, le nom d'utilisateur et le rôle. Ces déclarations sont généralement des données JSON. Le serveur signe ensuite ce jeton avec une clé pour assurer son intégrité et son authenticité.
Deuxièmement, après une authentification réussie, le serveur renvoie le JWT au client, qui est généralement stocké dans un emplacement sécurisé tel que les cookies HTTP ou le stockage local. Ce jeton sert de preuve d'authentification.
Enfin, pour les demandes ultérieures de protéger les ressources sur le serveur, le client ajoute un JWT à l'en-tête de demande, en utilisant généralement l'en-tête "Autorisation" avec le schéma "Bearer". Après avoir reçu le JWT, le serveur utilise la même clé utilisée pendant la création de jeton pour vérifier sa signature. De plus, il vérifie si le jeton n'a pas expiré et contient une déclaration valide. Après une vérification réussie, il extrait les informations utilisateur de la déclaration de jeton et met en œuvre la logique d'autorisation pour s'assurer que l'utilisateur a les autorisations nécessaires pour accéder à la ressource demandée. Cette approche permet une authentification sécurisée et sans état dans les applications PHP sans stockage côté serveur.
Bien que l'authentification JWT dans PHP offre de nombreux avantages tels que l'évolutivité et l'apatridie, les meilleures pratiques pour protéger les clés et l'adoption de la gestion des jetons sont essentiels pour maintenir la sécurité de votre application. L'utilisation de bibliothèques PHP JWT établies peut simplifier le traitement des jetons et améliorer la sécurité. L'alternative à JWT (jetons Web JSON) pour l'authentification et l'autorisation dans PHP est l'authentification basée sur la session. Dans l'authentification basée sur la session, le serveur maintient une session pour chaque utilisateur authentifié. Lorsque l'utilisateur se connecte, un identifiant de session unique est créé (généralement stocké sous forme de cookie de session sur le navigateur client). Cet identifiant est utilisé pour associer l'utilisateur aux données de session côté serveur, y compris des informations liées à l'utilisateur, telles que l'ID utilisateur, le nom d'utilisateur et les autorisations.
L'authentification basée sur la session offre une simplicité et une facilité d'implémentation, ce qui le rend adapté à une variété d'applications Web, surtout si vous n'avez pas besoin des capacités apatrides et évolutives de JWT. Il est avec état par nature, ce qui peut être avantageux lorsque vous devez gérer des données spécifiques à l'utilisateur (telles que le contenu de panier ou les préférences utilisateur) pendant une session utilisateur.
Cependant, il y a quelques éléments à considérer lors de l'utilisation de l'authentification basée sur la session. Il peut ne pas être tout à fait applicable pour les architectures distribuées ou basées sur des microservices qui nécessitent une authentification sans état. De plus, la gestion des sessions utilisateur peut augmenter la charge du serveur, en particulier dans les applications avec des bases utilisateur plus grandes. En fin de compte, le choix de JWT et l'authentification basée sur la session dans PHP devrait correspondre aux besoins spécifiques et aux considérations de conception de l'application pour garantir le mieux qu'un mécanisme d'authentification sécurisé répond au mieux à vos besoins. La protection de l'API PHP avec JWT (Tokens Web JSON) implique un processus en plusieurs étapes qui combine l'authentification et l'autorisation. Tout d'abord, sélectionnez la bibliothèque PHP JWT appropriée (telle que "Firebase / PHP-JWT" ou "LcoBUCCI / JWT") pour gérer les opérations liées au jeton et utiliser le compositeur pour gérer les dépendances.
Pour l'authentification, vous devez implémenter un système d'authentification utilisateur dans votre application PHP. Ce système vérifie les informations d'identification de l'utilisateur par rapport à votre base de données ou fournisseur d'authentification. Après une authentification réussie, vous générerez un jeton JWT contenant des affirmations liées à l'utilisateur telles que l'ID, le nom d'utilisateur et le rôle de l'utilisateur. Assurez-vous de définir le temps d'expiration pour contrôler la validité du jeton, puis signer le jeton avec la clé. Ce jeton signé est renvoyé au client dans le cadre de la réponse d'authentification.
Les clients stockent en toute sécurité le JWT reçu, généralement dans les cookies HTTP ou le stockage local. Pour les demandes d'API suivantes, le client inclura un JWT dans l'en-tête de demande en tant qu'en-tête "Autorisation" avec le schéma "Bearer". Dans votre API PHP, vous pouvez vérifier le JWT entrant en vérifiant sa signature en utilisant la même clé utilisée lors de la création du jeton. De plus, vous vérifiez que le jeton n'a pas expiré et contient une déclaration valide. Après une vérification réussie, vous extraire les informations de l'utilisateur de la déclaration de jeton et implémentez la logique d'autorisation pour vous assurer que l'utilisateur a les autorisations requises pour accéder à la ressource demandée.
Garder la clé en sécurité est crucial car il est crucial pour signer et vérifier le jeton. Toute fuite de cette clé peut conduire à une grave vulnérabilité de sécurité. pouvons-nous utiliser JWT en php?
Qu'est-ce que l'authentification JWT dans PHP?
Quelle est l'alternative à JWT dans PHP?
Comment protéger l'API PHP à l'aide de JWT?
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!