2008-09-10 4 views
4

Supposons qu'un utilisateur navigue sur un site Web, puis exécute une action qui modifie la base de données (ajoutons un commentaire). Cependant, lorsque la demande d'ajout du commentaire arrive, nous constatons que nous devons les forcer à se connecter avant de pouvoir continuer.Conserver les données HTTP POST lorsqu'une requête est interrompue par une page de connexion

Supposons que la page de connexion demande un nom d'utilisateur et un mot de passe, et redirige l'utilisateur vers l'URL vers laquelle il se dirigeait lorsque la connexion était requise. Cette redirection fonctionne pour une URL avec uniquement des paramètres GET, mais si la requête contenait à l'origine des données HTTP POST, elle est maintenant perdue.

Quelqu'un peut-il recommander un moyen de gérer ce scénario lorsque des données HTTP POST est impliqué? Évidemment, si nécessaire, la page de connexion peut générer dynamiquement un formulaire avec tous les paramètres POST pour les transmettre (bien que cela semble désordonné), mais même alors, je ne connais pas de façon pour la page de connexion à rediriger l'utilisateur sur sa page prévue tout en conservant les données POST dans la demande.


Modifier: Une contrainte supplémentaire que j'aurais clairement - Imaginez que nous ne savons pas si une connexion est nécessaire jusqu'à ce que l'utilisateur soumet son commentaire. Par exemple, leur cookie a peut-être expiré entre le chargement du formulaire et l'envoi du commentaire.

Répondre

2

2 choix:

  1. Dressez la forme désordonnée de la page de connexion, et JavaScript form.submit() à la page.
  2. Avoir la page de connexion elle-même POST à ​​la page de demande (avec les valeurs précédentes), et le contrôleur de cette page effectue la vérification de connexion. Roulez cela dans la logique que vous avez déjà pour détecter l'utilisateur non connecté (les frameworks varient en fonction de ce qu'ils font).Dans pseudo-MVC:

     CommentController { 
      void AddComment() { 
      if (!Request.User.IsAuthenticated && !AuthenticateUser()) { 
       return; 
      } 
      // add comment to database 
      } 

      bool AuthenticateUser() { 
      if (Request.Form["username"] == "") { 
       // show login page 
       foreach (Key key in Request.Form) { 
        // copy form values 
        ViewData.Form.Add("hidden", key, Request.Form[key]); 
       } 
       ViewData.Form.Action = Request.Url; 

       ShowLoginView(); 
       return false; 
       } else { 
       // validate login 
       return TryLogin(Request.Form["username"], Request.Form["password"]); 
       } 
      } 
     } 
11

Ceci est un bon endroit où les techniques Ajax pourraient être utiles. Lorsque l'utilisateur clique sur le bouton Soumettre, affiche la boîte de dialogue de connexion côté client et valide avec le serveur avant de soumettre la page.

Une autre façon dont je peux penser est d'afficher ou de masquer dynamiquement les contrôles de connexion dans une balise DIV dans la page principale elle-même.

1

Collectez les données sur la page où elles ont été soumises et stockez-les dans votre backend (base de données?) Lorsqu'elles passent par la séquence de connexion, masquez un ID de transaction ou similaire sur la page avec le formulaire de connexion. Quand ils ont fini, retournez-les à la page qu'ils ont demandée en la recherchant en utilisant l'ID de transaction sur le backend, et vider toutes les données qu'ils ont postées dans le formulaire pour prévisualiser à nouveau, ou simplement exécuter le code que cette page exécuterait. Notez que de nombreux systèmes, par exemple les blogs, contourner ce problème en ayant des champs de connexion dans le même formulaire que celui pour l'affichage des commentaires, si l'utilisateur doit être connecté pour commenter et ne l'est pas encore.

2

Il suffit de stocker toutes les données nécessaires du POST dans la session jusqu'à ce que le processus de connexion soit terminé. Ou avoir une sorte de table temporaire dans la base de données pour stocker et ensuite récupérer. De toute évidence, il s'agit d'un pseudo-code mais:

if (!loggedIn) { 
    StorePostInSession(); 
    ShowLoginForm(); 
} 

if (postIsStored) { 
    RetrievePostFromSession(); 
} 

Ou quelque chose du genre.

1

Je sais que ce langage dit agnostique, mais pourquoi ne pas tirer parti des conventions prévues par le langage côté serveur que vous utilisez? Si c'était Java, les données pourraient persister en définissant un attribut Request. Vous utiliseriez un contrôleur pour traiter le formulaire, détecter la connexion, puis passer à travers. Si les attributs sont définis, pré-remplissez simplement le formulaire avec ces données? Comme vous pouvez le constater, vous pouvez également utiliser une session, mais je suis sûr que si vous utilisez un forward en Java vers la page de connexion, l'attribut Request va persister.

3

Vous voudrez peut-être étudier pourquoi Django removed this feature avant de l'implémenter vous-même. Cela ne semble pas être un problème spécifique à Django, mais plutôt une autre attaque de contrefaçon intersite.

Questions connexes