Skip to content

38. Uygulama alıştırması: sürüm 18

38.1. Uygulama

Image

[impots/http-servers/13] dosyası, başlangıçta [impots/http-servers/12] dosyasının kopyalanmasıyla elde edilir ve ardından kısmen değiştirilir.

İlk olarak, [configs/parameters] dosyasına yeni bir parametre ekliyoruz:


…        
         # CSRF jetonu
        "with_csrftoken"False,
        # yönetilen veritabanları: MySQL (mysql), PostgreSQL (pgres)
        "databases"["mysql""pgres"],
        # uygulamanın URL önekleri
        # Önek istemiyorsanız dizgiyi boş bırakın, aksi takdirde /önek değerini girin
        "prefix_url""/do",
        # Apache sunucusunun kök URL'si - Apache dışında çalıştırmak için dizgiyi boş bırakın
        "application_root""/impots"

  1. satırda, [application_root] parametresi, Apache sanal sunucusunun WSGI takma adını temsil edecektir.

Bu parametre sayesinde, hataya neden olan [responses/HtmlResponse] komutunu düzeltebiliriz:

Image



# Şimdi, istenirse CSRF jetonunu da eklemeyi unutmadan yönlendirme URL'sini oluşturmalısınız
        if config['parameters']['with_csrftoken']:
            csrf_token = f"/{generate_csrf()}"
        else:
            csrf_token = ""

        # yönlendirme yanıtı
        return redirect(f"{config['parameters']['application_root']}{config['parameters']['prefix_url']}{ads['to']}{csrf_token}")
, status.HTTP_302_FOUND
  • 9. satır: Yönlendirme hedefinin başına uygulamanın kök dizinini ekledik;

Ayrıca, içerdikleri URL'lerin uygulama kök dizininden (veya WSGI takma adından) başlaması için tüm parçaları düzeltmemiz gerekiyor:

Image

[v-authentification] parçası


<!-- HTML formu - değerler, [authentifier-utilisateur] eylemi ile gönderilir -->
<form method="post" action="{{modèle.application_root}}{{modèle.prefix_url}}/authentifier-utilisateur{{modèle.csrf_token}}"
>

    <!-- başlık -->
    <div class="alert alert-primary" role="alert">
        <h4>Veuillez vous authentifier</h4>
    </div>


</form>

[v-calcul-impot] parçası


<!-- gönderilen HTML formu -->
<form method="post" action="{{modèle.application_root}}{{modèle.prefix_url}}/calculer-impot{{modèle.csrf_token}}">
    <!-- mavi arka planlı 12 sütunlu mesaj -->
    

</form>

[v-liste-simulations] parçası




{% if modèle.simulations is defined and modèle.simulations|length!=0 %}


<!-- simülasyon tablosu -->
<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 %}

[v-menu] parçası


<!-- Bootstrap menüsü -->
<nav class="nav flex-column">
    <!-- bağlantı listesinin görüntülenmesi 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>

Yukarıdaki parçaların tümü [modèle.application_root] şablonunu kullanmaktadır. Şu anda, şablon sınıfları tarafından oluşturulan şablonlarda [application_root] anahtarı mevcut değildir.

Image

Şablon oluşturan tüm sınıfların üst sınıfı olan [AbstractBaseModelForView] sınıfı şu şekilde olur:


from abc import abstractmethod

from flask import Request
from flask_wtf.csrf import generate_csrf
from werkzeug.local import LocalProxy

from InterfaceModelForView import InterfaceModelForView

class AbstractBaseModelForView(InterfaceModelForView):

    @abstractmethod
    def get_model_for_view(self, request: Request, session: LocalProxy, config: dict, résultat: dict) -> dict:
        pass

    def update_model(self, modèle: dict, config: dict):
        # jeton hesaplama CSRF
        if config['parameters']['with_csrftoken']:
            csrf_token = f"/{generate_csrf()}"
        else:
            csrf_token = ""
        # parametre olarak geçirilen şablonun güncellenmesi
        modèle.update({
            # CSRF jetonu
            'csrf_token': csrf_token,
            # prefix_url
            'prefix_url': configQZXW2HTMLBWyJwYXJhbWV0ZXJzIl0ZQXQZXW2HTMLBWyJwcmVmaXhfdXJsIl0ZQX,
            # application_root
            'application_root': configQZXW2HTMLBWyJwYXJhbWV0ZXJzIl0ZQXQZXW2HTMLBWyJhcHBsaWNhdGlvbl9yb290Il0ZQX,
        })
  • 15. satır: [update_model] yöntemi, şablona görünümleri ekleme görevini üstlenir:
    • 24. satır: CSRF jetonu;
    • 26. satır: URL önekidir;
    • 28. satır: uygulamanın kökü veya WSGI takma adı;

Dört alt sınıf, aşağıdaki kodla üst sınıfa başvurur:



        # görünümden gerçekleştirilebilecek eylemler
        modèle['actions_possibles'] = ["afficher-vue-authentification""authentifier-utilisateur"]

        # üst sınıf tarafından modelin tamamlanması
        super().update_model(modèle, config)

        # şablonu oluşturuyoruz
        return modèle
  • 6. satır: Her alt sınıf, oluşturduğu modeli güncellemek için üst sınıfını çağırır;

Sürüm 18 hazırdır. Sürüm 17'deki iki Apache sanal sunucusunu alıp değiştiriyoruz:

Image

[flask-impots-withXX.conf] adlı iki dosya yalnızca tek bir noktada değiştirilmiştir:


# .wsgi betiğinin bulunduğu klasör
define ROOT "C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/impots/http-servers/13/apache"

# bu dosya tarafından yapılandırılan web sitesinin adı
# burada adı flask-impots-withmysql olacak
# URL türünde olacak: http(s)://flask-impots-withmysql/yol
define SITE "flask-impots-withmysql"

# c:/windows/system32/drivers/etc/hosts dosyasına, IP 127.0.0.1 adresini SITE sitesi için ekleyin

# Buraya kullanılacak Python kütüphanelerinin yollarını girin - virgülle ayırın
# buraya bir Python sanal ortamının kütüphanelerini yazın
WSGIPythonPath  "C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/venv/lib/site-packages"

# Python Home - yalnızca birden fazla Python sürümü yüklüyse gereklidir
# WSGIPythonHome "C:/Program Files/Python38"

# URL HTTP
<VirtualHost *:80>
    # takma adıyla / URL, /{prefixe_url}/action/... biçiminde olacaktır
    # /impots takma adıyla, URL şu biçimi alacaktır: /impots/{prefixe_url}/action/...
    # burada [prefixe_url], parameters.py içinde tanımlanmıştır
    WSGIScriptAlias /impots "${ROOT}/main_withmysql.wsgi"
    …
</VirtualHost>

# URL, HTTPS ile güvenli hale getirilmiştir
<VirtualHost *:443>
    # takma adıyla / URL, /{prefixe_url}/action/... biçiminde olacaktır
    # takma adı /impots olan URL, /impots/{prefixe_url}/action/... biçiminde olacaktır
    # burada [prefixe_url], parameters.py içinde tanımlanmıştır
    WSGIScriptAlias /impots "${ROOT}/main_withmysql.wsgi"
    ..

</VirtualHost>
  • 12. satırda artık [impots/http-servers/13/apache] dosyası kullanılmaktadır.

Apache üzerine taşınan sürüm 18'in testlerine hazırız. Yapılandırma şu şekildedir:

  • WSGI takma adı, her iki sanal sunucu yapılandırma dosyasında da /impots olarak geçmektedir;
  • [configs/parameters] yapılandırma dosyasında parametreler şu şekildedir:

        # CSRF jetonu
        "with_csrftoken"False,
        # uygulamanın URL önekleri
        # Önek istemiyorsanız dizgiyi boş bırakın, aksi takdirde /önek yazın
        "prefix_url""/do",
        # Apache sunucusunun kök URL'si - Apache dışında çalıştırmak için dizgiyi boş bırakın
        "application_root""/impots"

Apache sunucusunu ve iki SGBD sunucusunu başlatıyoruz. URL ve [https://flask-impots-withmysql/impots/do] adreslerine erişim talebinde bulunuyoruz. Sunucudan gelen yanıt şu şekildedir:

Image

Önceki sürümde elde edemediğimiz kimlik doğrulama ekranı artık düzgün bir şekilde görüntüleniyor. Uygulamanın geri kalanı normal şekilde çalışıyor.

Şimdi diğer sanal sunucuyu test ediyoruz. URL ve [https://flask-impots-withpgres/impots/do] isteklerini gönderiyoruz. Sunucunun yanıtı şu şekildedir:

Image

WSGI takma adı ve URL önek kavramları aynı işlevi görüyor. Bu iki kavramdan biri gereksizdir. Dolayısıyla, Apache sunucusundaki URL adreslerine [/impots/do] dizesini önek olarak eklemek için üç farklı yol izlenebilir:

1 – [WGSIAlias /impots] ve [prefix_url=’/do’];

2 – [WGSIAlias /] ve [prefix_url=’/impots/do’];

3 - [WGSIAlias /impots/do] ve [prefix_url=’’];

38.2. Konsol testleri

Yine [http-clients/09] istemcisinin konsol testleri kullanılır:

Image

  • sunucudaki URL, [1] ve [3] yapılandırmalarında değiştirilmelidir;
  • Apache sunucusunun HTTPS protokolünü desteklemesi için [dao] katmanında bir değişiklik yapılmalıdır;

[config] dosyalarında, sunucunun URL değeri şu şekilde değiştirilir:


        "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": {
                
            }
        },
        # hata ayıklama modu
        "debug"True,
        # csrf_token
        "with_csrftoken"False,
  • 4. satır: sunucunun yeni URL değeri. Bu belgede ilk kez, istemci HTTPS protokolünü kullanır;

[dao] katmanındaki [ImpôtsDaoWihHttpSession] sınıfı şu şekilde değişir:


…    
     # istek / yanıt aşaması
    def get_response(self, method: str, url_service: str, data_value: dict = None, json_value=None):
        # [method] : HTTP, GET veya POST yöntemi
        # [url_service] : URL hizmeti
        # [data] : POST'in x-www-form-urlencoded biçimindeki parametreleri
        # [json] : POST parametreleri (json formatında)
        # [cookies]: isteğe eklenecek çerezler

        # XML veya JSON oturumu olmalıdır, aksi takdirde yanıtı işleyemeyiz
        if self.__session_type not in ['json''xml']:
            raise ImpôtsError(73"il n'y a pas de session valide en cours")

        # URL hizmet isteğine CSRF jetonunu ekleyin
        if self.__csrf_token:
            url_service = f"{url_service}/{self.__csrf_token}"

        # isteğin yürütülmesi
        response = requests.request(method,
                                    url_service,
                                    data=data_value,
                                    json=json_value,
                                    cookies=self.__cookies,
                                    allow_redirects=True,
                                    # https protokolü için
                                    verify=False)

        # hata ayıklama modu mu?
        if self.__debug:
            # giriş yapan
            if not self.__logger:
                self.__logger = self.__config['logger']
            # giriş yapılıyor
            self.__logger.write(f"{response.text}\n")

        

        # sonuç veriliyor
        return résultat['réponse']
  • 26. satırda, Apache sunucusu tarafından kullanılan HTTPS protokolü nedeniyle [verify=False] parametresi eklenir. [requests] modülü (19. satır), HTTPS protokolünü yerel olarak yönetebilir. Varsayılan olarak, HTTPS sunucusundan gönderilen güvenlik sertifikasının geçerliliğini kontrol eder ve alınan sertifika geçerli değilse bir istisna oluşturur. Laragon’daki Apache sunucusunun kendinden imzalı bir sertifika gönderdiği bu durumda da durum böyledir. İstisnayı önlemek için, [verify=False] parametresini kullanarak [requests] modülüne istisna oluşturmamasını söyleriz. Böylece [requests], konsolda sadece bir uyarı (warning) görüntüler.

Bu değişiklikler yapıldıktan sonra, tüm konsol testleri çalışmalıdır.