Angular Universal projeler için Backend Mimarisi


Selam takipçilerim,

Katmanlı mimari ile hazırladığınız bir .NET Core backendin endpointlerini doğru tasarlamak gerekiyor.

Angular Universal ile hazırladığımız frontend şunlar olacaktır:

  1. Angular Universal SSR Web Sitesi
  2. Ionic Angular Universal iOS Uygulama
  3. Ionic Angular Universal Android Uygulama
  4. Electron Angular Universal Mac Uygulama
  5. Electron Angular Universal Windows Uygulama
  6. Electron Angular Universal Linux Uygulama
  7. Angular CRM Web Uygulaması
  8. Ionic Angular CRM iOS Uygulama
  9. Ionic Angular CRM Android Uygulama

Temel olarak 9 client öngörebiliriz. Bunların ilk 6’sı aslında tek bir Angular Universal uygulamadır.

.NET Core Api katmanındaki endpointler şöyle olmalıdır:

  1. /api/auth
  2. /api/public
  3. /api/buyer -> Authorize(Roles = “Buyer”)
  4. /api/seller -> Authorize(Roles = “Seller”)

Buyer ve Seller web apilerinin ayrıştırılması bizim her ikisinde de ayrı ayrı JWT Authorize işlemi yapmamızı mümkün kılıyor. Ayrıca rolleri de ayrıştırarak güvenliği sağlamış oluyoruz. Ayrıca her controller kendi audienceCheck’ini de ayrı ayrı yapmalıdır.

Bu durumda CQRS Servis katmanında birden fazla rol kontrolüne implemente etmeniz gerekir.

KVKK konusunda yapılacaklar ise şöyledir:

  1. Üyelik sistemi olarak .NET Core Identity kullanılmalıdır.
  2. Serilog ile Error ve Information log sistemi kurulmalı ve Loglar veritabanına kaydedilmelidir. Request logu da aynı tabloya kaydedilebilir.
  3. EntityFrameworkCore için AuditLog implementasyonu yapılmalıdır.
  4. Oturum açma ve kapatma işlemleri için LoginLog implementasyonu yapılmalıdır.
  5. Oturum kapatıldığında ilgili JWT geçersiz kabul edilmeli ve sonraki kullanımlarında kabul edilmemelidir.
  6. Tüm kişisel veriler veritabanına ProtectedPersonalData ile şifrelenerek kaydedilmelidir.
  7. Parolalar veritabanına şifrelenerek kaydedilmelidir.
  8. Tekrar tekrar oturum açma işlemlerinde hesap kilitlenmelidir.
  9. Kişisel verilerin indirilebilmesi ve silinebilmesi sağlanmalıdır.
  10. İki faktörlü kimlik doğrulamasından yararlanılmalıdır.
  11. Parola değiştirildiğinde mevcut tüm JWT’ler geçersiz hale getirilerek oturumlar kapatılmalıdır.

Daha Fazla Güvenlik Gerekiyorsa:

  1. İki faktörlü kimlik doğrulaması mecburi yapılmalıdır.
  2. Yedek telefon ve kurtarma kodu implementasyonu yapılmalıdır.
  3. Periyodik parola değiştirme implementasyonu yapılmalıdır.
  4. Oturum açıldığında e-posta bildirimi gönderilmelidir.
  5. İki faktörlü kimlik doğrulamasında kolaylık için tarayıcıya güven özelliği implemente edilmelidir.

KVKK için Alınacak Temel Önlemler


1. Üyelik sistemi güçlü parola istemeli, parolaların periyodik olarak değiştirilmesini istemelidir

2. Oturum açılırken tekrar tekrar deneme yaparak parolayı bulmaya önlem alınmalıdır

3. Kişisel veriler ve parolalar veritabanına şifrelenerek kaydedilmelidir

4. Zaman damgalı erişim logları tutulmalıdır

5. Sunucularda ve istemcilerde Linux/Pardus işletim sistemleri kullanılmalıdır

6. Zaman damgalı log tutan firewall kullanılmalıdır

7. Sunucularda ve istemcilerde antivirüs ve antispyware yazılımları kullanılmalıdır

8. Sunucu ve istemci arasındaki erişimler şifreli (VPN/SSL) olmalıdır

9. Kullanıcının kişisel verilerini silebilmesi sağlanmalıdır

10. AuditLog tutulmalıdır

11. Yerli bulutlar tercih edilmelidir, yedeklerin ve logların güvenliği sağlanmalıdır

12. DLP ve CM yazılımları kullanılmalıdır.

Firebase Hosting’te Angular SSR Uygulama Nasıl Yayınlanır?


Yazılım konusunda ilerlemeye devam ediyorum. Bu makalede yeni edindiğim bilgileri paylaşacağım.

Öncelikle Backendi .NET Core olan Frontendi Angular Universal olarak bir e-ticaret sitesi hazırlıyor olsaydanız katmanlar nasıl olurdu hızlıca bir göz atalım tekrardan:

  1. Commerce.Buyer / Angular Universal SSR projesi (web sitesi)
  2. Commerce.Seller / Angular Universal proje
  3. Commerce.Api / .NET Core Web API projesi
  4. Commerce.Service / .NET Core sınıf kitaplığı
  5. Commerce.Infrastructure / .NET Core sınıf kitaplığı
  6. Commerce.Data / .NET Core sınıf kitaplığı
  7. Commerce.Model / .NET Core sınıf kitaplığı
  8. Commerce.Tests / .NET Core NUnit proje

Tüm katmanları gördünüz. Ancak yakın zamanda .NET Core’un Application Insights ve Telemetery kütüphanelerinin casusluk yaptığına dair bilgiye ulaştım. Windows 10’da bulunan Telemetery hizmeti bilgisayarınızda bilgileri arka planda Microsoft sunucularına gönderiyor. Bu bilgileri yapay zekaları eğitmek için kullanıyorlar diye tahmin ediyorum. Bill Gates geçenlerde bu işi 20 yıl önce yapmadığına pişman olduğunu ifade etmişti.

Anlayacağınız Windows KVKK açısından güvenli bir işletim sistemi değil. .NET Core ‘da aynı şekilde.

Ancak .NET Core’u Linux üzerinde kullandığınızda Application Insights/Telemetery entegrasyonu çalışmıyor.

Bu durumda KVKK uyumlu yazılım geliştirmek istiyorsanız şunlara dikkat etmelisiniz.

  1. Pardus işletim sistemini kullanın, Pardus’u hem backend sunucusu hem de geliştirim ortamı olarak kullanabilirsiniz.
  2. SQL Server’ı ve .NET Core’u Pardus'(lar)a yükleyin.
  3. SQL Server’ı TDE ile şifreleyin ve güvenlik özelliklerini aktifleştirin.
  4. SQL Server’daki ApplicationUser entity’sindeki ve varsa diğer entitylerdeki kişisel verileri ProtectedPersonalData attribute’unu kullanarak şifreleyin.
  5. Şifreleme algoritmalarında RSA, SHA1, SHA256 eski algoritmalar yerine post-kuantum güvenlik algoritmalarını tercih edin.
  6. Yurtdışı bulutları yerine yurtiçi bulutları tercih edin.
  7. Veritabanı AuditLog’unu etkinleştirin.
  8. EntityFramework için AuditLog geliştirin.
  9. Oturum açma/kapama işlemlerini ve kişisel verilere erişimleri loglayın.
  10. Loglardaki tarih/saat verilerini güvenli zaman-damgalarıyla üretip kaydedin.
  11. Logları koruyun.

Kaspersky siber saldırıların artış göstereceği bir döneme gireceğimiz konusunda bizleri uyarmıştı. Gerekli önlemleri aldığınızda hem kişisel verileri korumuş olacak hem de siber saldırılara dirençli olacaksınız.

Şimdi gelelim asıl konumuza…

Angular Universal ile bir e-ticaret sitesi hazırlıyorsanız Ionic ve Cordova sayesinde kolaylıkla hibrit mobil uygulamaları hazırlayabiliyorsunuz. Ayrıca Angular Universal ile web sitesi de hazırlamış oluyorsunuz. Fakat siteniz komple JavaScript projesi olduğundan Google gibi arama motorları web sitenizdeki sayfaları indeksleyemiyor. SSR ile bu problemi çözebiliyoruz.

Web sitesini Firebase’te yayınlayacaksanız bu kez de SSR’la nasıl yayınlayacağız diye bir soru işareti oluşuyor. Aşağıdaki maddeleri takip ederek Angular Universal SSR projesini Firebase Hosting’de deploy edebilirsiniz. Aşağıdaki komutları Terminal’de Commerce.Buyer dizinindeyken çalıştırmalısınız:

  1. Öncelikle SSR’ın gerçekten çalıştığından emin olun: npm run build:ssr ve npm run serve:ssr komutları ile test edin.
  2. Eğer daha önce yüklemediyseniz npm install -g firebase-tools komutu ile Firebase Araçlarını yükleyin.
  3. firebase login komutu ile eğer talep edilirse e-posta ve parolanızla oturum açın.
  4. firebase init komutunu çalıştırın
  5. Çıkan soruları cevaplayın:
    1. “Are you ready to proceed?”
      y yazıp ENTER’a basın.
    2. “Which firebase CLI features do you want to setup?”
      Space tuşuyla Functions ve Hosting’i seçip ENTER’a basın.
    3. “Select a default Firebase project for this directory?”
      Ok tuşları ile uygun olanı seçip ENTER’a basın.
    4. “What language would you like to use to write Cloud Functions?”
      Ok tuşları ile TypeScript’i seçip ENTER’a basın.
    5. “Do you want to use TSLint?”
      y yazıp ENTER’a basın.
    6. “Do you want to install dependencies with npm now?”
      y yazıp ENTER’a basın.
    7. “What do you want to use as your public directory?”
      dist/browser yazıp ENTER’a basın. (Dikkat: Angular Universal olmayan projede bu kısım farklıdır)
    8. “Configure as a single page app?”
      y yazıp ENTER’a basın.
    9. File index.html already exists. Overwrite?
      n yazıp (önemli!) ENTER’a basın.
  6. Şimdi bazı dosyaları düzenleyin:
    1.  firebase.json dosyasında "destination": "/index.html" ifadesini "function": "ssr" olarak değiştirin.
      (ssrexport const ssr = functions.https.onRequest(universal); değişkenini ifade eder, bunu aşağıda göreceksiniz.)
    2. server.ts dosyasına export to the app başlatısını ekleyin: const app = express(); yerine export const app = express();
    3. server.ts dosyasında son üç satırı yorum satırı yapın (app.listen(...)) or ya da onları aşağıdaki ile değiştirin:
 // If we're not in the Cloud Functions environment, spin up a Node server
    if (!process.env.FUNCTION_NAME) {
        // Start up the Node server
        app.listen(PORT, () => {
            console.log(`Node Express server listening on http://localhost:${PORT}`);
        });
    }

Bu kodları Firebase deploy ederken kaldırabilirsiniz fakat bu kodlar localhost üzerinde npm run serve:ssr ile uygulamayı çalıştırabilmek için gereklidir.

4. webpack.server.config.js dosyasında output aşağıdaki gibi değiştirin:

 output: {
        // Puts the output at the root of the dist folder
        path: path.join(__dirname, 'dist'),
        // Export a UMD of the webpacked server.ts & dependencies for rendering in Cloud Functions
        library: 'app',
        libraryTarget: 'umd',
        filename: '[name].js',
    },

ve externals’ı aşağıdaki gibi değiştirin:

externals: [
        // Firebase has some troubles being webpacked when it's in the Node environment, so we will skip it.
        /^firebase/
    ],

Bu npm run serve:ssr or firebase serve komutlarıyla çalıştırında oluşan aşağıdaki hatayı düzeltecektir:

Cannot find module ‘require(“./server/main”)’

  5. npm run build:ssr komutunu çalıştırarak uygulamayı tekrar derleyin.

6. cd functions ile functions dizine girin.

7. Dosya sistemi erişimi için npm pakedi yükleyin: npm i fs-extra

8. functions dizini içinde copy-angular-app.js adında yeni bir dosya oluşturun içine şunları yazın:

const fs = require('fs-extra');
    fs.copy('../dist', './dist').then(() => {
        // We should remove the original "index.html" since Firebase will use it when SSR is enabled (instead of calling SSR functions),
        // and because of that, SSR won't work for the initial page.
        fs.remove('../dist/browser/index.html').catch(e => console.error('REMOVE ERROR: ', e));
    }).catch(err => {
        console.error('COPY ERROR: ', err)
    });

 Bu SSR ile ilgili ilk sayfanın yüklenememe problemini düzeltir.

  Not: index.html dosyasını kaldırdığımız için, npm run serve:ssr çalışmayacaktır (npm run build:ssr -> bunu çalıştırırsanız index.html dosyasını tekrar oluşturacaktır.

9. functions/package.json dosyasında (projenin package.json dosyası DEĞİL!) build satırını aşağıdaki şekilde değiştirin:

"build": "node copy-angular-app && tsc",

10. functions/src/index.ts dosyasında içeriği şöyle değiştirin:

    import * as functions from 'firebase-functions';

    const universal = require(`${process.cwd()}/dist/server`).app;
    export const ssr = functions.https.onRequest(universal);

11. Terminaldeyken functions dizininde olduğunuzdan emin olun ve  npm run build komutunu çalışıtırın böylece dist klasörü functions klasörüne kopyalanacaktır.

Ek not: Build işlemini kolaylaştırmak için ana projenin package.json dosyasında şunları düzenleyebilirsiniz:

    "build:ssr": "npm run build:client-and-server-bundles && npm run compile:server", // this one should already exist
    "build:ssr-firebase": "npm run build:ssr && npm --prefix functions/ run build",

Bu script öncelikle Angular SSR uygulamasını derleyecektir (npm run build:ssr) ve sonra functions dizininde npm run build çalıştıracaktır (böylece dist dizini functions  a kopyalanacaktır ve projenin index.html dosyasını kaldıracatır)

Şimdi uygulamayı yayınlayın …

  • firebase serve komutu ile  localhost:5000 üzerinden yerel yayınlama yapabilirsiniz (eğer isterseniz).
  • Sunucuyu durdurun (Ctrl + C).
  • firebase deploy uygulamayı yayınlayabilir ve terminalde çıkan adresten uygulamayı ziyaret edebilirsiniz.

NOT: Tüm bunlar yerine yeni çıkan ng deploy‘u kullanmayı deneyin. Bu daha basit yol, her ne kadar bugları olabilse de.

Mutlu kodlamalar 🙂