Skip to content

12. Applicazione Web MVC [person] – Versione 7

12.1. Introduzione

In questa versione, si ipotizza che possano esserci browser client che hanno disabilitato:

  1. l'invio di cookie dal server
  2. l'esecuzione del codice JavaScript incorporato nelle pagine HTML visualizzate

Ciononostante, vogliamo che questo tipo di browser sia in grado di utilizzare la nostra applicazione. Il punto 2 ci riporta alla versione 2 della nostra applicazione, poiché JavaScript è stato introdotto a partire dalla versione 3. La versione 2 eseguiva l'applicazione senza JavaScript, quindi il punto 2 è risolto.

Il punto 1 potrebbe essere difficile da gestire o meno. La versione 6 della nostra applicazione funzionava senza cookie. Unendo le versioni 2 e 6, otteniamo il risultato desiderato. Aggiungeremo un ulteriore vincolo: l'applicazione deve gestire una sessione. Non si tratta di un vincolo privo di significato. In un'applicazione in cui gli utenti devono autenticarsi, il server deve memorizzare il nome utente e la password dell'utente per evitare che questi debba autenticarsi su ogni pagina richiesta.

Finora abbiamo utilizzato tre soluzioni per memorizzare le informazioni durante gli scambi client/server:

  1. la sessione
  2. i cookie
  3. i campi nascosti.

La soluzione 2 può essere esclusa poiché il browser del client potrebbe aver disabilitato i cookie.

La soluzione 3 è quella della versione 6, che abbiamo esaminato in precedenza. Non può essere utilizzata per motivi di sicurezza. Se la coppia login/password è incorporata in ogni pagina inviata al browser, ciò significa che viaggia sulla rete ad ogni scambio client-server. Questo non va bene per la sicurezza dell'applicazione. Potremmo quindi considerare l'utilizzo del protocollo HTTPS, che crittografa gli scambi client-server. Tuttavia, utilizzarlo per ogni pagina dell'applicazione aumenterà il carico del server.

Potresti voler escludere la Soluzione 1 perché si basa anche sui cookie. Durante il primo scambio client-server, il server invia al client un token di sessione, che il client poi rispedisce al server con ogni nuova richiesta. Grazie a questo token, il server può riconoscere il client e fornirgli le informazioni che aveva memorizzato durante uno scambio precedente. Il token di sessione viene inviato dal server in un cookie. Un browser che non ha disabilitato i cookie può rinviare questo cookie al server nelle richieste successive. Se i cookie sono disabilitati, esiste un'altra soluzione: il browser può includere il token di sessione nell'URL che richiede. Questo è ciò che vediamo ora mentre rivisitiamo il file [index.jsp] della versione 4:


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>
 
<c:redirect url="/main"/>

Ricordiamo che la riga 5 sopra reindirizza il client all'URL [/personne4/main?jsessionid=XX], dove XX è il token di sessione, come mostrato nella schermata qui sotto ottenuta dopo aver richiesto l'URL [http://localhost:8080/personne4]:

Image

Diamo un'occhiata più da vicino a come funziona il tag <c:redirect> in relazione al token di sessione. Utilizziamo un browser che accetta i cookie. Di seguito, configuriamo il browser Firefox:

Image

In [1] abilitiamo i cookie e in [2] eliminiamo quelli esistenti per partire da uno stato noto. Quindi richiediamo l'URL [http://localhost:8080/personne4]. Riceviamo la seguente risposta:

Image

La richiesta HTTP iniziale del client era la seguente:

1
2
3
4
5
6
7
8
9
GET /personne4/ HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: fr-fr,fr;q=0.8,en;q=0.6,en-us;q=0.4,de;q=0.2
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive

Si noti che il client non invia un cookie di sessione. La risposta HTTP inviata dal server è la seguente:

1
2
3
4
5
6
7
HTTP/1.x 302 Déplacé Temporairement
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=1ACA010A6BA28FB9E30A1D3184F574BC; Path=/personne4
Location: http://localhost:8080/personne4/main;jsessionid=1ACA010A6BA28FB9E30A1D3184F574BC
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 0
Date: Tue, 23 May 2006 09:10:05 GMT
  • Riga 1: il server chiede al client di reindirizzare
  • riga 3: il server invia un token di sessione associato all'attributo [JSESSIONID]
  • riga 4: l'URL di reindirizzamento contiene il token di sessione. Il tag <c:redirect> lo ha inserito lì perché il client non aveva inviato un cookie di sessione.

Il browser, a cui era stato chiesto di reindirizzarsi, ha quindi effettuato la seguente richiesta:

GET /personne4/main;jsessionid=1ACA010A6BA28FB9E30A1D3184F574BC HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: fr-fr,fr;q=0.8,en;q=0.6,en-us;q=0.4,de;q=0.2
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cookie: JSESSIONID=1ACA010A6BA28FB9E30A1D3184F574BC
  • Riga 1: Richiede l'URL di reindirizzamento, incluso il token di sessione. Questo è il motivo per cui il browser visualizza questo URL nello screenshot.
  • Riga 10: il browser rispedisce il token di sessione che il server gli ha inviato nello scambio precedente. È così che funzionano normalmente i cookie quando sono abilitati sul browser client. Se non sono abilitati, i cookie ricevuti non vengono rispediti.

Il server ha risposto a questa seconda richiesta con quanto segue:

1
2
3
4
5
HTTP/1.x 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 2376
Date: Tue, 23 May 2006 09:10:05 GMT

Ha trovato la pagina richiesta e la sta inviando. Si noti che non invia più il token di sessione. Ecco come funzionano normalmente i token di sessione: il server lo invia al browser una volta sotto forma di cookie, e il browser lo rimanda poi con ogni richiesta per essere riconosciuto.

Ora, utilizzando lo stesso browser, richiediamo nuovamente l'URL [http://localhost:8080/personne4] digitandolo manualmente. Otteniamo quindi la seguente pagina:

Image

Possiamo notare che l'URL visualizzato dal browser non contiene più il token di sessione. Diamo un'occhiata al primo scambio client/server:

Il browser ha effettuato la seguente richiesta:

GET /personne4 HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: fr-fr,fr;q=0.8,en;q=0.6,en-us;q=0.4,de;q=0.2
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cookie: JSESSIONID=1ACA010A6BA28FB9E30A1D3184F574BC

Questa è esattamente la stessa richiesta della precedente, con una differenza: alla riga 10, il browser rinvia il token di sessione ricevuto durante il primissimo scambio. Anche in questo caso, si tratta di un comportamento normale se i cookie del browser sono abilitati.

Il server ha inviato la seguente risposta:

1
2
3
4
5
HTTP/1.x 302 Déplacé Temporairement
Server: Apache-Coyote/1.1
Location: http://localhost:8080/personne4/
Transfer-Encoding: chunked
Date: Tue, 23 May 2006 09:24:39 GMT

Indica al client di effettuare il reindirizzamento. Poiché ha ricevuto un token di sessione dal client, continua la sessione e non invia un nuovo token di sessione. Per lo stesso motivo, il tag <c:redirect> non include questo token di sessione nell'URL di reindirizzamento. Questo è il motivo per cui l'URL mostrato nella schermata sopra non contiene un token di sessione.

La conclusione fondamentale di tutto ciò è la seguente regola: il tag <c:redirect> include il token di sessione nell'URL di reindirizzamento solo se il client non ha inviato l'intestazione HTTP:

Cookie: JSESSIONID=1ACA010A6BA28FB9E30A1D3184F574BC

Questa regola si applica anche al tag <c:url>, che vedremo più avanti.

Cosa succede con un browser su cui i cookie sono stati disabilitati? Proviamo. Per prima cosa, resettiamo il browser:

Image

In [1] disabilitiamo i cookie e in [2] eliminiamo quelli esistenti per partire da uno stato noto. Quindi richiediamo l'URL [http://localhost:8080/personne4]. Otteniamo la seguente risposta:

Image

Otteniamo lo stesso risultato di prima. Tuttavia, gli scambi HTTP non sono esattamente gli stessi:

GET /personne4/ HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: fr-fr,fr;q=0.8,en;q=0.6,en-us;q=0.4,de;q=0.2
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive

HTTP/1.x 302 Déplacé Temporairement
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=911B8156E0A9D32C2D256020C898E05C; Path=/personne4
Location: http://localhost:8080/personne4/main;jsessionid=911B8156E0A9D32C2D256020C898E05C
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 0
Date: Tue, 23 May 2006 09:39:55 GMT

GET /personne4/main;jsessionid=911B8156E0A9D32C2D256020C898E05C HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: fr-fr,fr;q=0.8,en;q=0.6,en-us;q=0.4,de;q=0.2
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive

HTTP/1.x 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 2376
Date: Tue, 23 May 2006 09:39:55 GMT
  • Righe 1–9: la prima richiesta del browser. Non invia un cookie di sessione.
  • Righe 11–17: La risposta del server, che indica al browser di reindirizzarsi a un altro URL. Invia un cookie di sessione. Riga 13: Il tag <c:redirect> ha incluso il token nell'URL di reindirizzamento alla riga 14.
  • Righe 19–27: La seconda richiesta del browser. Non restituisce il cookie di sessione che il server ha appena inviato perché i suoi cookie sono disabilitati.
  • Righe 29–33: La risposta del server. Possiamo notare che, sebbene il browser non abbia inviato un cookie di sessione, il server non avvia una nuova sessione come ci si potrebbe aspettare. Ciò è evidente dal fatto che non invia l'intestazione HTTP [Set-Cookie] come ha fatto alla riga 13. Ciò significa che continua la sessione precedente. È stato in grado di recuperare questa sessione grazie al token di sessione presente nell'URL richiesto dal browser alla riga 19.

Si noti che il server tiene traccia di una sessione recuperando il token di sessione inviato dal client in due modi possibili:

  • nell'intestazione HTTP [Set-Cookie] inviata dal client
  • nell'URL richiesto dal client

Ora, utilizzando lo stesso browser, richiediamo nuovamente l'URL [http://localhost:8080/personne4] digitandolo manualmente, proprio come abbiamo fatto quando i cookie erano abilitati. Otteniamo quindi la seguente pagina:

Image

Il risultato è diverso da quello che abbiamo visto quando i cookie erano abilitati: il token di sessione è nell'URL visualizzato dal browser. Spieghiamo questo risultato senza esaminare gli scambi HTTP che hanno avuto luogo:

[cookie abilitati]

  • Durante la seconda richiesta dell'URL [http://localhost:8080/personne4], il browser client ha rinviato il cookie di sessione che aveva ricevuto dal server durante la prima richiesta per quello stesso URL. Il tag <c:redirect> non ha quindi incluso il token di sessione nell'indirizzo di reindirizzamento.

[cookie disabilitati]

  • Durante la seconda richiesta per l'URL [http://localhost:8080/personne4], il browser client non invia il cookie di sessione ricevuto dal server durante la prima richiesta per lo stesso URL, poiché i cookie sono disabilitati. Il tag <c:redirect> include quindi il token di sessione nell'URL di reindirizzamento. Questo è il motivo per cui appare nella schermata sopra.

I tag <c:redirect> e <c:url> consentono di includere il token di sessione negli URL. Questa è la soluzione qui proposta.

12.2. Il progetto Eclipse

Per creare il progetto Eclipse [mvc-personne-07] per l'applicazione web [/personne7], duplicare il progetto [mvc-personne-06] seguendo la procedura descritta nella sezione 6.2.

12.3. Configurazione dell'applicazione web [personne7]

Il file web.xml per l'applicazione /personne7 è il seguente:


<?xml version="1.0" encoding="UTF-8"?>
...
    <display-name>mvc-personne-07</display-name>
...

Questo file è identico a quello della versione precedente, tranne che per la riga 3, dove il nome visualizzato dell'applicazione web è cambiato in [mvc-personne-07]. La pagina iniziale [index.jsp] rimane invariata.


...
<c:redirect url="/do/formulaire"/>

12.4. Il codice della vista

Le viste [form, response, errors] tornano a essere come nella versione 2, ovvero senza JavaScript. Tuttavia, mantengono i tag JSTL delle ultime versioni.

12.4.1. La vista [form]

Image

I pulsanti associati al codice JavaScript sono stati rimossi.

[form.jsp]:


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
  pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>
 
<html>
  <head>
    <title>Personne - formulaire</title>
  </head>
  <body>
    <center>
      <h2>Personne - formulaire</h2>
      <hr>
      <form name="frmPersonne" action="<c:url value="validationFormulaire"/>" method="post">
        <table>
          <tr>
            <td>Nom</td>
            <td><input name="txtNom" value="${nom}" type="text" size="20"></td>
          </tr>
          <tr>
            <td>Age</td>
            <td><input name="txtAge" value="${age}" type="text" size="3"></td>
          </tr>
          <tr>
        </table>
        <table>
          <tr>
            <td><input type="submit" name="bouton" value="Envoyer"></td>
            <td><input type="reset" value="Rétablir"></td>
            <td><input type="submit" name="bouton" value="Effacer"></td>
          </tr>
        </table>
      </form>
    </center>
  </body>
</html>
  • Riga 14: L'URL di destinazione POST è scritto utilizzando il tag <c:url> in modo che il token di sessione sia incluso nel caso in cui il client sia un browser che non invia l'intestazione HTTP [Cookie].
  • Il modulo ha due pulsanti [submit]: [Submit] (riga 28) e [Clear] (riga 30). Entrambi i pulsanti hanno lo stesso nome: button. Quando viene attivato il POST, il browser invierà il parametro:
  • button=Submit se il POST è stato attivato dal pulsante [Submit]
  • button=Clear se il POST è stato attivato dal pulsante [Clear]

Questo parametro ci aiuterà a determinare l'azione esatta da intraprendere, poiché l'URL [/do/validationFormulaire] ora corrisponde a due azioni distinte.

12.4.2. La vista [response]

Image

[response.jsp]:


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>
 
<html>
    <head>
      <title>Personne</title>
  </head>
  <body>
      <h2>Personne - réponse</h2>
    <hr>
    <table>
        <tr>
          <td>Nom</td>
        <td>${nom}</td>
      </tr>
        <tr>
          <td>Age</td>
        <td>${age}</td>
      </tr>
    </table>      
    <br>
    <a href="<c:url value="retourFormulaire"/>">${lienRetourFormulaire}</a>
  </body>
</html>
 
  • Riga 24: L'URL di destinazione dell'HREF viene scritto utilizzando il tag <c:url> in modo che il token di sessione sia incluso nel caso in cui il client sia un browser che non invia l'intestazione HTTP [Cookie].

12.4.3. La vista [errors]

Image

[errors.jsp]:


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>
 
<html>
    <head>
      <title>Personne</title>
  </head>
  <body>
      <h2>Les erreurs suivantes se sont produites</h2>
    <ul>
            <c:forEach var="erreur" items="${erreurs}">
                <li>${erreur}</li>
            </c:forEach>
    </ul>
    <br>
    <a href="<c:url value="retourFormulaire"/>">${lienRetourFormulaire}</a>
  </body>
</html>
 
  • Riga 18: L'URL di destinazione HREF viene scritto utilizzando il tag <c:url> in modo che il token di sessione sia incluso nel caso in cui il client sia un browser che non invia l'intestazione HTTP [Cookie].

I lettori sono invitati a testare queste nuove viste utilizzando lo stesso approccio delle versioni precedenti.

12.5. Il controller [ServletPersonne]

Il controller [ServletPersonne] per l'applicazione web [/personne7] è il seguente:

package istia.st.servlets.personne;

...

@SuppressWarnings("serial")
public class ServletPersonne extends HttpServlet {
    // instance parameters
    private String urlErreurs = null;
    private ArrayList erreursInitialisation = new ArrayList<String>();
    private String[] paramètres={"urlFormulaire","urlReponse","lienRetourFormulaire"};
    private Map params=new HashMap<String,String>();

    // init
    @SuppressWarnings("unchecked")
    public void init() throws ServletException {
...
    }

    // GET
    @SuppressWarnings("unchecked")
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {

...
        // retrieve the request sending method
        String méthode=request.getMethod().toLowerCase();
        // retrieve the action to be executed
        String action=request.getPathInfo();
...
        if(méthode.equals("post") && action.equals("/validationFormulaire")){
            // validation of input form
            doValidationFormulaire(request,response);
            return;
        }
        if(méthode.equals("get") && action.equals("/retourFormulaire")){
            // back to input form
            doRetourFormulaire(request,response);
            return;
        }
        // other cases
        doInit(request,response);
    }

    // empty form display
    void doInit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
...
    }

    // display pre-filled form
    void doRetourFormulaire(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        // the form is displayed
        getServletContext().getRequestDispatcher((String)params.get("urlFormulaire")).forward(
                request, response);
        return;
    }

    // empty form display
    void doEffacer(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        // prepare the form template
        HttpSession session = request.getSession(true);        
        session.setAttribute("nom", "");
        session.setAttribute("age", "");
        // the form is displayed
        getServletContext().getRequestDispatcher((String)params.get("urlFormulaire")).forward(
                request, response);
        return;
    }

    // form validation
    void doValidationFormulaire(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException{
        // we retrieve the button that caused the POST
        String bouton = request.getParameter("bouton").toLowerCase();
        // treatment according to the button that caused the POST
        if(bouton==null){
            doInit(request,response);
            return;
        }
        if("envoyer".equals(bouton)){
            doEnvoyer(request,response);
            return;
        }
        if("effacer".equals(bouton)){
            doEffacer(request,response);
            return;
        }
    }

    // form validation
    void doEnvoyer(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException{
        // parameters are retrieved
        String nom = request.getParameter("txtNom");
        String age = request.getParameter("txtAge");
        // stored in the session
        HttpSession session = request.getSession(true);        
        session.setAttribute("nom", nom);
        session.setAttribute("age", age);
        // the link back to the form is set in the view template [response, errors]
        request.setAttribute("lienRetourFormulaire", (String)params.get("lienRetourFormulaire"));    
        // parameter verification
        ArrayList<String> erreursAppel = new ArrayList<String>();
    ...
        // errors in the parameters?
        if (erreursAppel.size() != 0) {
            // send error page
            request.setAttribute("erreurs", erreursAppel);
            getServletContext().getRequestDispatcher(urlErreurs).forward(
                    request, response);
            return;
        }
        // parameters are correct - send response page
        getServletContext().getRequestDispatcher((String)params.get("urlReponse")).forward(request,
                response);
        return;
    }

    // post
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
...
    }
}
  • riga 35: l'azione [/retourFormulaire] viene eseguita tramite una richiesta GET anziché una richiesta POST come nella versione precedente.
  • righe 70–87: l'azione [/validationFormulaire] viene attivata da una richiesta POST generata dal clic su uno dei pulsanti [Envoyer] o [Effacer] nella vista [form]. Il metodo [doValidationFormulaire] gestisce questi due casi utilizzando due metodi diversi.
  • righe 90–103: il metodo [doEnvoyer] corrisponde al metodo [doValidationFormulaire] della versione precedente. I dati inseriti vengono memorizzati nella sessione (righe 96–98), mentre nella versione precedente venivano inseriti nella richiesta.
  • Righe 58–67: Il nuovo metodo [doEffacer] deve visualizzare un modulo vuoto. Potremmo chiamare il metodo [doInit], che svolge già questo compito. Qui, cogliamo l’occasione per cancellare anche gli elementi [name, age] dalla sessione in modo che continui a riflettere lo stato più recente del modulo.
  • Righe 50-55: richiedono la visualizzazione della vista [form] senza alcuna inizializzazione apparente del modello della vista. Questo modello è in realtà composto dagli elementi [name, age] già presenti nella sessione. Non è richiesta alcuna ulteriore azione.

12.6. Test

Avviare o riavviare Tomcat dopo aver integrato il progetto Eclipse [personne-mvc-07], quindi richiedere l'URL [http://localhost:8080/personne7] utilizzando un browser con i cookie disabilitati e quelli esistenti cancellati. Si ottiene la seguente risposta:

Image

Il codice sorgente ricevuto dal browser è il seguente:

1
2
3
<form name="frmPersonne" action="validationFormulaire;jsessionid=9D4CC83FEFB51AE78B1FD71EC66F9EF3" method="post">
...
</form>

Riga 1: Il token di sessione si trova nell'URL di destinazione POST.

Compiliamo il modulo e inviamolo:

Image

Il codice sorgente ricevuto dal browser è il seguente:

1
2
3
4
...
    <br>
    <a href="retourFormulaire;jsessionid=9D4CC83FEFB51AE78B1FD71EC66F9EF3">Retour au formulaire</a>
  </body>

Riga 3: Il token di sessione si trova nell'URL di destinazione del link.