38. Esercizio pratico: Versione 18
38.1. Implementazione

La cartella [impots/http-servers/13] viene inizialmente creata copiando la cartella [impots/http-servers/12] e poi parzialmente modificata.
Iniziamo aggiungendo un nuovo parametro al file [configs/parameters]:
…
# token csrf
"with_csrftoken": False,
# bases gérées MySQL (mysql), PostgreSQL (pgres)
"databases": ["mysql", "pgres"],
# préfixe des URL de l'application
# mettre la chaîne vide si on ne veut pas de préfixe ou /préfixe sinon
"prefix_url": "/do",
# url racine du serveur Apache - mettre la chaîne vide pour une exécution en-dehors d'Apache
"application_root": "/impots"
…
Riga 10: Il parametro [application_root] rappresenterà l'alias WSGI del server virtuale Apache.
Con questo parametro, possiamo correggere la direttiva [responses/HtmlResponse] che ha causato l'errore:

…
# now it's time to generate the URL redirection, not forgetting the CSRF token if requested
if config['parameters']['with_csrftoken']:
csrf_token = f"/{generate_csrf()}"
else:
csrf_token = ""
# redirect response
return redirect(f"{config['parameters']['application_root']}{config['parameters']['prefix_url']}{ads['to']}{csrf_token}")
, status.HTTP_302_FOUND
- riga 9: abbiamo aggiunto la radice dell'applicazione all'inizio dell'URL di destinazione del reindirizzamento;
Dobbiamo anche correggere tutti i frammenti in modo che gli URL in essi contenuti inizino con la radice dell'applicazione (o l'alias WSGI):

Il frammento [v-authentication]
<!-- form HTML - post its values with the [authenticate-user] action -->
<form method="post" action="{{modèle.application_root}}{{modèle.prefix_url}}/authentifier-utilisateur{{modèle.csrf_token}}"
>
<!-- title -->
<div class="alert alert-primary" role="alert">
<h4>Veuillez vous authentifier</h4>
</div>
…
</form>
Il frammento [v-calcul-impot]
<!-- form HTML posted -->
<form method="post" action="{{modèle.application_root}}{{modèle.prefix_url}}/calculer-impot{{modèle.csrf_token}}">
<!-- 12-column message on blue background -->
…
</form>
Il frammento [v-liste-simulations]
…
{% if modèle.simulations is defined and modèle.simulations|length!=0 %}
…
<!-- simulation table -->
<table class="table table-sm table-hover table-striped">
…
<tr>
<th scope="row">{{simulation.id}}</th>
<td>{{simulation.marié}}</td>
<td>{{simulation.enfants}}</td>
<td>{{simulation.salaire}}</td>
<td>{{simulation.impôt}}</td>
<td>{{simulation.surcôte}}</td>
<td>{{simulation.décôte}}</td>
<td>{{simulation.réduction}}</td>
<td>{{simulation.taux}}</td>
<td><a href="{{modèle.application_root}}{{modèle.prefix_url}}/supprimer-simulation/{{simulation.id}}{{modèle.csrf_token}}">Supprimer</a></td>
</tr>
{% endfor %}
</tr>
</tbody>
</table>
{% endif %}
Il frammento [v-menu]
<!-- bootstrap menu -->
<nav class="nav flex-column">
<!-- display a list of links HTML -->
{% for optionMenu in modèle.optionsMenu %}
<a class="nav-link" href="{{modèle.application_root}}{{modèle.prefix_url}}{{optionMenu.url}}{{modèle.csrf_token}}">{{optionMenu.text}}</a>
{% endfor %}
</nav>
I frammenti sopra riportati utilizzano tutti il modello [model.application_root]. Attualmente, la chiave [application_root] non esiste nei modelli generati dalle classi modello.

La classe [AbstractBaseModelForView], che è la classe padre di tutte le classi che generano un modello, diventa la seguente:
- riga 15: il metodo [update_model] è responsabile dell'aggiunta di quanto segue al modello di visualizzazione:
- riga 24: il token CSRF;
- riga 26: il prefisso URL;
- riga 28: la radice dell'applicazione o l'alias WSGI;
Le quattro classi figlie chiamano la classe padre con il seguente codice:
…
# actions possibles à partir de la vue
modèle['actions_possibles'] = ["afficher-vue-authentification", "authentifier-utilisateur"]
# finition du modèle par la classe parent
super().update_model(modèle, config)
# on rend le modèle
return modèle
- riga 6: ogni classe figlia chiama la classe padre per aggiornare il modello che ha creato;
La versione 18 è pronta. Riutilizziamo i due server virtuali Apache della versione 17 e li modifichiamo:

I due file [flask-impots-withXX.conf] vengono modificati in un unico punto:
# dossier du script .wsgi
define ROOT "C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/impots/http-servers/13/apache"
# nom du site web configuré par ce fichier
# ici il s'appellera flask-impots-withmysql
# les URL seront du type http(s)://flask-impots-withmysql/path
define SITE "flask-impots-withmysql"
# mettre l'adresse IP 127.0.0.1 pour site SITE dans c:/windows/system32/drivers/etc/hosts
# mettre ici les chemins des bibliothèques Python à utiliser - les séparer par des virgules
# ici les bibliothèques d'un environnement virtuel Python
WSGIPythonPath "C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/venv/lib/site-packages"
# Python Home - nécessaire uniquement s'il y a plusieurs versions de Python installées
# WSGIPythonHome "C:/Program Files/Python38"
# URL HTTP
<VirtualHost *:80>
# avec l'alias / les URL auront la forme /{prefixe_url}/action/...
# avec l'alias /impots les URL auront la forme /impots/{prefixe_url}/action/...
# où [prefixe_url] est défini dans parameters.py
WSGIScriptAlias /impots "${ROOT}/main_withmysql.wsgi"
…
</VirtualHost>
# URL sécurisées avec HTTPS
<VirtualHost *:443>
# avec l'alias / les URL auront la forme /{prefixe_url}/action/...
# avec l'alias /impots les URL auront la forme /impots/{prefixe_url}/action/...
# où [prefixe_url] est défini dans parameters.py
WSGIScriptAlias /impots "${ROOT}/main_withmysql.wsgi"
..
</VirtualHost>
- Riga 12: Ora stiamo utilizzando la directory [taxes/http-servers/13/apache].
Siamo pronti a testare la versione 18 in esecuzione su Apache. La configurazione è la seguente:
- l'alias WSGI è /impots in entrambi i file di configurazione dei server virtuali;
- nel file di configurazione [configs/parameters], i parametri sono i seguenti:
# token csrf
"with_csrftoken": False,
# préfixe des URL de l'application
# mettre la chaîne vide si on ne veut pas de préfixe ou /préfixe sinon
"prefix_url": "/do",
# url racine du serveur Apache - mettre la chaîne vide pour une exécution en-dehors d'Apache
"application_root": "/impots"
Avviamo il server Apache e i due DBMS. Richiediamo l'URL [https://flask-impots-withmysql/impots/do]. La risposta del server è la seguente:

Riusciamo a visualizzare correttamente la pagina di autenticazione, alla quale non potevamo accedere nella versione precedente. Il resto dell'applicazione funziona normalmente.
Ora proviamo l'altro server virtuale. Richiediamo l'URL [https://flask-impots-withpgres/impots/do]. La risposta del server è la seguente:

I concetti di alias WSGI e prefissi URL hanno lo stesso scopo. Uno di questi due concetti è ridondante. Pertanto, per anteporre agli URL del server Apache la stringa [/impots/do], ci sono tre modi per farlo:
1 – [WGSIAlias /impots] e [prefix_url=’/do’];
2 – [WGSIAlias /] e [prefix_url=’/impots/do’];
3 – [WGSIAlias /impots/do] e [prefix_url=’’];
38.2. Test della console
Utilizziamo nuovamente i test della console client [http-clients/09]:

- l'URL del server deve essere modificato nelle configurazioni [1] e [3];
- è necessario apportare una modifica al livello [dao] in modo che supporti il protocollo HTTPS del server Apache;
Nei file [config], l'URL del server diventa il seguente:
"server": {
# "urlServer": "http://127.0.0.1:5000",
# "urlServer": "http://127.0.0.1:5000/do",
"urlServer": "https://flask-impots-withmysql/impots/do",
"user": {
"login": "admin",
"password": "admin"
},
"url_services": {
…
}
},
# mode debug
"debug": True,
# csrf_token
"with_csrftoken": False,
- riga 4: il nuovo URL del server. Per la prima volta in questo documento, il client utilizza il protocollo HTTPS;
La classe [ImpôtsDaoWihHttpSession] nel livello [dao] si evolve come segue:
- Alla riga 26, aggiungiamo il parametro [verify=False] a causa del protocollo HTTPS utilizzato dal server Apache. Il modulo [requests] (riga 19) supporta nativamente il protocollo HTTPS. Per impostazione predefinita, verifica la validità del certificato di sicurezza inviato dal server HTTPS e genera un'eccezione se il certificato ricevuto non è valido. Questo è il caso in cui il server Apache di Laragon invia un certificato autofirmato. Per evitare l'eccezione, utilizziamo il parametro [verify=False] per indicare al modulo [requests] di non generare un'eccezione. [requests] visualizza quindi semplicemente un avviso sulla console.
Una volta apportate queste modifiche, tutti i test da console dovrebbero funzionare.