bouton et action

comment faire un button qui fait une action

Le problème exposé dans ce sujet a été résolu.

Bonjour,

j’ai deux questions,
je développe un petit dashboard qui affiche les containers docker qui tourne, j’utilise pour chaque container une card de bulma .
1) J’ai comme dans l’exemple des boutons

<footer class="card-footer">
    <a href="#" class="card-footer-item">Save</a>
    <a href="#" class="card-footer-item">Edit</a>
    <a href="#" class="card-footer-item">Delete</a>
  </footer>

maintenant j’aimerais connecter ces boutons a des actions réels. Comment je fais ? si je met dans le href un lien du style monApi/container/<action>/id ou action est un de save Edit, Delete il suffit que qqun donne le lien tonDashBoard.com/monApi/container/delete/beaucoupDessai il me faut un token csrf je crois ?

Je le met comment dans mon tag a ? est-ce que c’est pas la bonne méthode ?

2) mon site est en go+gin, j’ai le code suivant :

<div class="columns is-centered">
            {{range $i, $c := .containers}}
           <div class="column has-text-centered is-narrow">
               <div class="card">
                   <div class="card-header is-size-5 has-text-centered">
                       <p class="card-header-title has-text-centered">
                           {{index $c.Names 0 }}...
                       </p>
                   </div>
                   <div class="card-content ">
                       <div class="content has-text-black is-size-4">
                           {{$c.State}}
                           
                       </div>
                       <footer class="card-footer">
                           <a href="#" class="card-footer-item">
                               <span>
                                   Start
                               </span>
                           </a>
                           <a href="#" class="card-footer-item">
                               <span>
                                   Stop
                               </span>
                           </a>
                           <a href="#" class="card-footer-item is-danger">
                               <span>
                                   Remove
                               </span>
                           </a>
                       </footer>
                   </div>
               </div>
           </div>
           {{end}}

Cependant lorsque il y a plus de 5 cards, elles ne s’ajustent pas les unes sur les autres et j’ai une ligne qui dépasse la taille de mon écran. Comment dire à Bulma de faire plusieurs ligne si les colonnes ne tiennent pas sur une seule ligne ?
J’ai trouvé pour 2) : is-multiline

Merci d’avance :)

+0 -0

Salut ! Pour le second problème, tu peux ajouter la classe is-multiline à l’élément parent (le .columns) (documentation) pour que les colonnes passent à la ligne automatiquement.

Pour le premier problème c’est plus un souci de conception du backend. Tes requêtes ne sont pas authentifiées ? Si elles le sont, y’a plus de souci de ce genre (et pour des actions aussi importantes, elles devraient l’être). Un jeton CSRF peut aider à sécuriser le truc, oui. Je n’ai jamais utilisé gin, je ne saurais donc t’aiguiller sur comment l’implémenter, cela dit.

+2 -0

ouais mais en soit une authentification ne sert a rien contre un lien qui fait une action non ? puisque le cookie de session sera donnée lorsque l’admin clique sur le lien, il sera authentifié comme admin pour l’action.

Ouais pour l’instant je fais des testes en local, sans authentification je vais pas tarder a l’ajouter

+0 -0

ouais mais en soit une authentification ne sert a rien contre un lien qui fait une action non ? puisque le cookie de session sera donnée lorsque l’admin clique sur le lien, il sera authentifié comme admin pour l’action.

Ouais pour l’instant je fais des testes en local, sans authentification je vais pas tarder a l’ajouter

d3m0t3p

J’ai pas compris ce que tu voulais dire, mais si, c’est à ça que ça sert. Quand tu cliques sur le lien, tu envoies aussi ton authentification. Côté serveur, tu vérifies qu’elle bonne et tu exécutes ou non l’action.

+1 -0

Ici il est plus précisément question d'autorisation en général plutôt que d’authentification spécifiquement. Quand l’utilisateur effectue une action, le backend vérifie qu’il a l’autorisation de le faire :

  • est-il connecté (authentifié et/ou identifié) ?
  • si oui, cet utilisateur dispose-t-il des droits suffisants pour effectuer l’action ?
  • si non, est-ce qu’on autorise quand même ? (par exemple parce qu’on est en mode DEV ou DEBUG ou que sais-je)
  • est-ce que le contexte de la requête permet de faire l’action ? Par exemple en vérifiant un token CSRF, un referrer, vérifier que la requête soit faite en HTTPS, exiger un cookie avec SameSite=Strict, etc.

ouais mais en soit une authentification ne sert a rien contre un lien qui fait une action non ? puisque le cookie de session sera donnée lorsque l’admin clique sur le lien, il sera authentifié comme admin pour l’action.

Si un acteur malicieux se procure de quoi rejouer la requête, oui. Sauf si tu mitiges ce risque. Mais la question, alors, c’est : quel est ton modèle de menace si spécifique qui justifierait de telles mesures ?

Dans le cas général, le modèle est plutôt simple : on part du principe que personne ne peut intercepter le cookie ou le token de connexion en vertu de la couche HTTPS, et on suppose aussi que la machine cliente est réputée sûre (pas une machine du cyber-café, pas une machine avec un malware qui lit les cookies, par exemple).

Dans cette configuration, il y a des attaques qui permettent de rejouer des requêtes à l’insu de l’utilisateur déjà authentifié (via son cookie) sur simple visite d’un site malicieux. La mitigation existe, elle consiste en un token CSRF et/ou une politique de cookie SameSite=Strict, ce qui est assez standard sur une application Web moderne.

Maintenant, si tu as des raisons de penser que la machine cliente ne peut être réputée sûre et que les cookies de connexion ont de fortes chances d’être compromis (en transit ou chez le client), alors tu as un modèle déjà plus complexe et d’autres mesures devront être implémentées. Est-ce que c’est possiblement ton cas ?

Alors non le projet n’est pas ici sérieux, c’est une machine qui fait tourner le site qui est dans un réseau privé, c’est juste pour comprendre les mécanismes de sécurités je connais de nom csrf mais je vois pas vraiment comment ça protège.
Prenons la situation où je suis authentifié, sur mon site avec un cookie de session et qu’une personne met dans son site un bouton qui a comme lien http://localhost/api/delete/all. Si je clique sur le bouton, mon navigateur va :

  1. Faire une requete GET api/delete/all sur localhost,
  2. donne mon cookie d’authentification (puisque je suis connecté)
  3. l’action est réalisée à mon insu.

Maintenant, si je met met Set-Cookie: authToken=….; SameSite=Strict Alors le cookie ne sera pas envoyé puisque le site qui initie la requête n’est pas le même que celui sur lequel le cookie est définie et donc l’action ne se fait pas, correcte ?

Maintenant pour le token CSRF je suis pas sur de comprendre, dans les exemples sur internet on voit

...
<input type="hidden" name="csrf-token" value="CIwNZNlR4XbisJF39I8yWnWX9wX4WFoz" />

Cependant,

  1. ça ne fonctionne pas avec une requête get ?

Si je comprends bien : le token csrf est dans le html donc à chaque fois que l’utilisateur se balade sur le site j’injecte le token dans les requêtes ce qui permet d’être sur que l’utilisateur qui fait une requête est bien entrain de se balader sur le site et a donc surement fait lui même l’action

Est-ce que faire une vérification au niveau de l’API ne serait pas plus simple? Je distribue à moi (comme je suis le seul utilisateur XD) un cookie de session, et lorsque je fais un appel get à l’API je fait GET /api/container/action/<Session-token> et de cette manière je peux vérifié que l’utilisateur a bien les droits pour le faire

+0 -0

Prenons la situation où je suis authentifié, sur mon site avec un cookie de session et qu’une personne met dans son site un bouton qui a comme lien http://localhost/api/delete/all. Si je clique sur le bouton, mon navigateur va :

  1. Faire une requete GET api/delete/all sur localhost,
  2. donne mon cookie d’authentification (puisque je suis connecté)
  3. l’action est réalisée à mon insu.

Et encore, c’est possible même sans action explicite ! Il suffit que le site malveillant fasse une requête AJAX dans le dos de l’utilisateur.

Maintenant, si je met met Set-Cookie: authToken=….; SameSite=Strict Alors le cookie ne sera pas envoyé puisque le site qui initie la requête n’est pas le même que celui sur lequel le cookie est définie et donc l’action ne se fait pas, correcte ?

L’action ne se fait pas si toutefois ton backend refuse de la faire. Mais en principe il refusera puisque, comme tu le dis, la requête ne sera pas authentifiée sans le cookie qui le permet.

Maintenant pour le token CSRF je suis pas sur de comprendre, dans les exemples sur internet on voit

...
<input type="hidden" name="csrf-token" value="CIwNZNlR4XbisJF39I8yWnWX9wX4WFoz" />

Cependant,

  1. ça ne fonctionne pas avec une requête get ?

Dans le principe, rien en t’empêcherait de mettre un token CSRF en query string avec un GET, mais ce n’est pas la méthode adéquate comme dit @Moté. Un POST est plus habituel pour cela (voire aussi PUT et DELETE selon le cas, si tu suis un style très RESTful).

Si je comprends bien : le token csrf est dans le html donc à chaque fois que l’utilisateur se balade sur le site j’injecte le token dans les requêtes ce qui permet d’être sur que l’utilisateur qui fait une requête est bien entrain de se balader sur le site et a donc surement fait lui même l’action

C’est l’idée, oui. Même si depuis un site tiers la requête est indûment authentifiée (dans le cas où il n’y a pas de SameSite=Strict et que le cookie est ré-utilisé par exemple), il serait en principe impossible d’avoir le bon token CSRF depuis ce site tiers. Donc le backend devrait refuser d’autoriser l’action sans ce token. Note que c’est à toi (ou à ton framework) d’implémenter la vérification du token CSRF, cependant.

Est-ce que faire une vérification au niveau de l’API ne serait pas plus simple?

C’est possible, bien-sûr. Mais là encore, ça dépend de tes besoins, lesquels dérivent des suppositions de sécurité que tu fais.

OK j’ai mieux compris les protections CSRF merci beaucoup :)

Cependant je pense atoujours voir un problème de conception/compréhension . j’ai dans le footer de ma carte (code copier/modifié dans l’exemple de la carte sur bulma)

<footer class="card-footer">
    <a href="apiv1/save/1234" class="card-footer-item">Delete</a>
</footer>

et j’ai un handler pour GET apiv1/save/, mais enfaite mon navigateur essaie de voir la page apiv1/save/1234 et on change de page, comment faire juste une requête http à la place et rester sur la même page ?

Je n’ai pas trouvé d’attribut pour le tag a qui permettrait de faire ça.

Mais je trouve sale de faire une forme hidden, avec un boutton qui submit la donnée. C’est comme ça que ça se fait pour faire un boutton qui fait un appel à une api ?

Enfin, c’est la bonne manière de faire, alors que je ne veut envoyer aucune information de faire une form ? Sinon comment connecter ce lien a mon api sans changer de page ? Est-ce que le problème viendrait de mon code serveur qui indique pas la bonne information au navigateur ?

+0 -0

Mais je trouve sale de faire une forme hidden, avec un boutton qui submit la donnée. C’est comme ça que ça se fait pour faire un boutton qui fait un appel à une api ?

Ce n’est pas sale de faire ça, c’est au contraire assez courant et c’est une bonne pratique pour faire ça :) . D’ailleurs, si tu regardes le lien de déconnexion sur ZdS, dans le menu en haut à droite…

<ul class="dropdown-list">
  
    <!-- … -->
    
    <li class="staff-only">
        <a href="/mise-en-avant/">Gestion des mises en avant</a>
    </li>

    <li>
        <form method="post" action="/membres/deconnexion/">
            <input type="hidden" name="csrfmiddlewaretoken" value="lacensureestpasséeparlà">
            <button type="submit">Déconnexion</button>
        </form>
    </li>
</ul>

…c’est exactement ce qu’on fait :) . Et en POST, ce qui est recommandé.

En résumé, deux façons de faire ça (toujours en POST ou similaire, en tout cas pas GET) :

  • passer par du JavaScript et envoyer une requête POST comme ça (par exemple, via fetch) ; ou
  • mettre un formulaire comme ci-dessus, avec un bouton stylisé comme tu le désires pour que ça se fonde dans le site, et rediriger vers la page d’origine après le traitement.
+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte