Takip et

Angular ve Auth0 Lock ile Güvenli Kimlik Doğrulama Rehberi

Günümüz modern web uygulamalarında güvenlik, yazılım geliştirme süreçlerinin en kritik unsurlarından biri haline gelmiştir.

Angular ve Auth0 Lock ile Güvenli Kimlik Doğrulama Rehberi

Günümüz modern web uygulamalarında güvenlik, yazılım geliştirme süreçlerinin en kritik unsurlarından biri haline gelmiştir. Kullanıcı verilerinin korunması, yetkisiz erişimlerin engellenmesi ve güvenli oturum yönetimi, tek sayfalı uygulamalarda (Single Page Applications – SPA) özel bir mimari yaklaşım gerektirir. Angular gibi güçlü ve modüler bir ön yüz çerçevesiyle çalışırken, kimlik doğrulama (Authentication) ve yetkilendirme (Authorization) altyapısını sıfırdan inşa etmek hem zaman alıcıdır hem de ciddi güvenlik risklerini beraberinde getirebilir.

Bu noktada Auth0, Bulut tabanlı Kimlik Hizmeti (Identity-as-a-Service – IDaaS) sağlayıcısı olarak devreye girer. Auth0, geliştiricilere ölçeklenebilir, güvenli ve esnek bir kimlik doğrulama ekosistemi sunar. Auth0’ın sunduğu en pratik çözümlerden biri olan Auth0 Lock, özelleştirilebilir, duyarlı (responsive) ve tüm modern giriş senaryolarını (kullanıcı adı/şifre, sosyal medya ile giriş, şifresiz giriş) destekleyen hazır bir kimlik doğrulama arayüzüdür (Widget). Bu makalede, Angular uygulamalarında Auth0 ve Auth0 Lock entegrasyonunu uçtan uca, mimari detayları ve en iyi uygulama standartlarıyla ele alacağız.

1. Temel Kavramlar ve Mimari Yapı

Angular uygulamasında Auth0 ve Auth0 Lock entegrasyonuna geçmeden önce, altta yatan protokollerin ve bileşenlerin nasıl çalıştığını anlamak kritik önem taşır.

OAuth 2.0 ve OpenID Connect (OIDC)

Auth0, standart olarak OAuth 2.0 yetkilendirme çerçevesini ve bunun üzerine inşa edilmiş OpenID Connect (OIDC) kimlik doğrulama katmanını kullanır. OAuth 2.0, uygulamanın kullanıcı adına kaynaklara erişmesini sağlarken; OIDC, kullanıcının kimliğini doğrular ve istemciye (Angular uygulaması) kullanıcı hakkında standart bilgiler (ID Token) sağlar.

Token Tipleri

Auth0 mimarisinde temel olarak iki tür token ile çalışılır:

  • ID Token: JSON Web Token (JWT) formatındadır. Kullanıcının kimlik bilgilerini (ad, e-posta, profil fotoğrafı vb.) içerir. İstemci tarafı (Angular) tarafından okunup kullanıcı arayüzünü şekillendirmek için kullanılır.
  • Access Token: Uygulamanın korunan arka plan (Backend API) servislerine istek yaparken sunduğu anahtardır. Bearer token olarak HTTP isteklerinin başlıklarına (Header) eklenir.

Auth0 Lock Nedir?

Auth0 Lock, tek bir bileşenle tüm kimlik doğrulama akışını yöneten bir JavaScript kütüphanesidir. Geliştiricileri her bir giriş türü için ayrı form tasarlama, validation yazma ve sosyal ağ entegrasyonları için ayrı SDK’lar bağlama yükünden kurtarır. Lock kütüphanesi, Auth0 backend’i ile doğrudan güvenli bir şekilde haberleşerek kullanıcı oturumunu açar ve gerekli token’ları Angular uygulamasına teslim eder.

2. Auth0 Dashboard Üzerinde Yapılandırma

Entegrasyonun ilk adımı, Auth0 yönetim panelinde (Dashboard) bir uygulama tanımlamak ve güvenlik parametrelerini ayarlamaktır.

Uygulama Oluşturma

  1. Auth0 hesabınıza giriş yapın ve Applications > Applications sekmesine gidin.
  2. Create Application butonuna tıklayın.
  3. Uygulamanıza bir isim verin (Örn: “Angular-Auth0-App”) ve tür olarak Single Page Web Applications seçeneğini işaretleyin.

Uygulama Ayarları (Application Settings)

Oluşturulan uygulamanın detay sayfasına girerek aşağıdaki parametrelerin yapılandırılması gerekir:

  • Domain: Auth0 kiracınızın (tenant) benzersiz adresidir (örn: dev-domain.us.auth0.com).
  • Client ID: Uygulamanızı Auth0 tarafında tanıtan açık kimlik bilgisidir.
  • Allowed Callback URLs: Auth0 Lock üzerinden başarılı giriş yapıldıktan sonra kullanıcının yönlendirileceği güvenli adreslerdir. Yerel geliştirme için http://localhost:4200 eklenmelidir.
  • Allowed Logout URLs: Oturum kapatıldığında kullanıcının yönlendirileceği adrestir. Yine http://localhost:4200 tanımlanmalıdır.
  • Allowed Web Origins: Cross-Origin Resource Sharing (CORS) güvenlik önlemi için uygulamanızın çalıştığı kök adrestir (http://localhost:4200).

3. Angular Projesinin Hazırlanması ve Bağımlılıkların Kurulması

Auth0 Lock kütüphanesini bir Angular projesine dahil etmek için gerekli npm paketlerinin kurulması ve ortam değişkenlerinin (environment) ayarlanması gerekir.

Paket Kurulumu

Terminal üzerinden projenizin kök dizininde aşağıdaki komutu çalıştırarak auth0-lock kütüphanesini ve TypeScript tip tanımlamalarını yükleyin:

npm install auth0-lock --save
npm install @types/auth0-lock --save-dev

Environment Yapılandırması

Auth0 bilgilerinizi kod içerisine sabit yazmak yerine Angular’ın src/environments/environment.ts dosyası içerisinde tutmak en doğru yaklaşımdır:

export const environment = {
  production: false,
  auth0: {
    domain: 'YOUR_AUTH0_DOMAIN.us.auth0.com',
    clientId: 'YOUR_AUTH0_CLIENT_ID',
    callbackURL: 'http://localhost:4200',
    audience: 'https://YOUR_AUTH0_DOMAIN.us.auth0.com/api/v2/'
  }
};

4. Auth0 Lock Servisinin (AuthService) Tasarlanması

Angular’da kimlik doğrulama mantığını bileşenlerden (Component) ayırarak merkezi bir servis (Injectable Service) içerisinde toplamak, kodun sürdürülebilirliği ve test edilebilirliği açısından elzemdir.

Aşağıda, Auth0 Lock bileşenini başlatan, olayları (events) dinleyen ve token yönetimini üstlenen örnek bir AuthService uygulaması yer almaktadır:

import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import Auth0Lock from 'auth0-lock';
import { environment } from '../../environments/environment';

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  private lock: Auth0LockStatic;

  constructor(private router: Router) {
    this.initLock();
    this.handleAuthentication();
  }

  private initLock(): void {
    const options: Auth0LockConstructorOptions = {
      auth: {
        redirectUrl: environment.auth0.callbackURL,
        responseType: 'token id_token',
        audience: environment.auth0.audience,
        params: {
          scope: 'openid profile email'
        }
      },
      autoclose: true,
      oidcConformant: true,
      theme: {
        logo: 'assets/logo.png',
        primaryColor: '#311b92'
      },
      languageDictionary: {
        title: "Güvenli Giriş"
      }
    };

    this.lock = new Auth0Lock(
      environment.auth0.clientId,
      environment.auth0.domain,
      options
    );
  }

  public login(): void {
    this.lock.show();
  }

  private handleAuthentication(): void {
    this.lock.on('authenticated', (authResult: any) => {
      if (authResult && authResult.accessToken && authResult.idToken) {
        this.setSession(authResult);
        this.router.navigate(['/dashboard']);
      }
    });

    this.lock.on('authorization_error', (error: any) => {
      console.error('Kimlik doğrulama hatası:', error);
    });
  }

  private setSession(authResult: any): void {
    const expiresAt = JSON.stringify((authResult.expiresIn * 1000) + new Date().getTime());
    localStorage.setItem('access_token', authResult.accessToken);
    localStorage.setItem('id_token', authResult.idToken);
    localStorage.setItem('expires_at', expiresAt);
  }

  public logout(): void {
    localStorage.removeItem('access_token');
    localStorage.removeItem('id_token');
    localStorage.removeItem('expires_at');
    this.router.navigate(['/']);
  }

  public isAuthenticated(): boolean {
    const expiresAt = JSON.parse(localStorage.getItem('expires_at') || '0');
    return new Date().getTime() < expiresAt;
  }

  public getAccessToken(): string | null {
    return localStorage.getItem('access_token');
  }
}

Kodun Teknik Analizi

  • new Auth0Lock(): Lock bileşenini yapılandırma ayarlarıyla birlikte başlatır. responseType: 'token id_token' seçeneği, başarılı giriş sonrası hem access hem de ID token dönmesini sağlar.
  • this.lock.on(‘authenticated’): Kullanıcı Lock ekranında başarılı şekilde oturum açtığında tetiklenen olay dinleyicisidir. Dönüş parametresi olan authResult nesnesi içerisinden token’lar alınır.
  • setSession(): Elde edilen token’ları ve geçerlilik süresini (expiration time) istemci tarafına kaydeder.
  • isAuthenticated(): Mevcut zaman ile token’ın son kullanma tarihini karşılaştırarak kullanıcının oturumunun geçerli olup olmadığını kontrol eder.

5. Angular Route Guard ile Sayfa Koruması

Yetkisiz kullanıcıların belirli rotalara (Route) erişimini engellemek için Angular’ın CanActivate veya güncel fonksiyonel guard yapıları kullanılır. Kullanıcı oturum açmamışsa otomatik olarak Lock ekranına veya ana sayfaya yönlendirilir.

Fonksiyonel mimariye uygun örnek bir AuthGuard tanımı:

import { inject } from '@angular/core';
import { CanActivateFn, Router } from '@angular/router';
import { AuthService } from './auth.service';

export const authGuard: CanActivateFn = (route, state) => {
  const authService = inject(AuthService);
  const router = inject(Router);

  if (authService.isAuthenticated()) {
    return true;
  } else {
    authService.login();
    return false;
  }
};

Bu Guard, app.routes.ts veya app-routing.module.ts içerisindeki rotalara şu şekilde eklenir:

import { Routes } from '@angular/router';
import { DashboardComponent } from './dashboard/dashboard.component';
import { authGuard } from './auth.guard';

export const routes: Routes = [
  { 
    path: 'dashboard', 
    component: DashboardComponent, 
    canActivate: [authGuard] 
  }
];

6. HTTP Interceptor ile Otomatik Token Ekleme

Kullanıcı doğrulandıktan sonra, Angular uygulamasının korunan API uç noktalarına yapacağı her istekte Access Token göndermesi gerekir. Bu işlem manuel yapılmak yerine bir HTTP Interceptor aracılığıyla otomatize edilir.

Aşağıda, istek başlığına Bearer Token ekleyen bir Interceptor örneği verilmiştir:

import { HttpInterceptorFn } from '@angular/common/http';
import { inject } from '@angular/core';
import { AuthService } from './auth.service';

export const jwtInterceptor: HttpInterceptorFn = (req, next) => {
  const authService = inject(AuthService);
  const token = authService.getAccessToken();

  if (token && authService.isAuthenticated()) {
    const cloned = req.clone({
      setHeaders: {
        Authorization: Bearer ${token}
      }
    });
    return next(cloned);
  }

  return next(req);
};

HTTP Interceptor, app.config.ts dosyası içerisinde provideHttpClient ile birlikte kaydedilmelidir:

import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { ApplicationConfig } from '@angular/core';
import { jwtInterceptor } from './jwt.interceptor';

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(withInterceptors([jwtInterceptor]))
  ]
};

7. Kullanıcı Profili Yönetimi

Auth0 Lock, kullanıcının e-posta adresi, adı ve profil resmi gibi temel bilgileri almanıza imkan tanır. Bu bilgilere erişmek için Lock nesnesinin getUserInfo metodundan faydalanılır.

AuthService sınıfına eklenebilecek profil getirme metodu:

public getUserProfile(callback: (err: any, profile: any) => void): void {
  const accessToken = this.getAccessToken();
  if (!accessToken) {
    callback('Access token bulunamadı', null);
    return;
  }

  this.lock.getUserInfo(accessToken, (error, profile) => {
    if (error) {
      console.error('Profil bilgisi alma hatası:', error);
      return callback(error, null);
    }
    callback(null, profile);
  });
}

Bileşen (Component) tarafında kullanım örneği:

import { Component, OnInit } from '@angular/core';
import { AuthService } from '../auth.service';

@Component({
  selector: 'app-user-profile',
  template: 
    <div *ngIf="userProfile" class="profile-card">
      <img [src]="userProfile.picture" alt="Profil Resmi" />
      <h3>{{ userProfile.name }}</h3>
      <p>{{ userProfile.email }}</p>
    </div>
  
})
export class UserProfileComponent implements OnInit {
  userProfile: any;

  constructor(private authService: AuthService) {}

  ngOnInit(): void {
    if (this.authService.isAuthenticated()) {
      this.authService.getUserProfile((err, profile) => {
        if (profile) {
          this.userProfile = profile;
        }
      });
    }
  }
}

8. Auth0 Lock Özelleştirme ve Tema Ayarları

Auth0 Lock’un en büyük avantajlarından biri, markanızın kurumsal kimliğine tam uyum sağlayacak şekilde özelleştirilebilmesidir. Lock yapılandırma nesnesi (Auth0LockConstructorOptions) üzerinden birçok görsel ve davranışsal parametre değiştirilebilir.

Görsel Tema Özelleştirmesi

theme: {
  logo: 'https://ornek-sitemiz.com/assets/logo.png',
  primaryColor: '#1E88E5',
  labeledSubmitButton: true
}

Türkçe Dil Desteği (Localization)

Auth0 Lock, varsayılan olarak İngilizce arayüzle gelir. Ancak languageDictionary özelliği veya dil seçeneği kullanılarak tamamen Türkçe hale getirilebilir:

language: 'tr',
languageDictionary: {
  emailInputPlaceholder: "yol@ornek.com",
  title: "Giriş Yapın",
  signUpTitle: "Kayıt Ol",
  passwordInputPlaceholder: "Şifreniz"
}

Giriş Yöntemlerini Sınırlandırma

Uygulamanızda yalnızca sosyal medya (Google, GitHub) veya yalnızca kurumsal DB bağlantılarını izinli kılabilirsiniz:

allowedConnections: ['google-oauth2', 'github', 'Username-Password-Authentication']

9. Güvenlik Best Practices (En İyi Uygulamalar)

Angular ve Auth0 Lock kullanırken güvenliği en üst seviyeye çıkarmak için aşağıdaki mimari kurallara dikkat edilmelidir:

1. Implicit Flow Yerine Authorization Code Flow with PKCE

Geleneksel SPA’larda kullanılan Implicit Flow (doğrudan token alma) güvenlik standartlarında artık önerilmemektedir. Bunun yerine Auth0 v12+ ve modern SPA standartlarında Authorization Code Flow with PKCE (Proof Key for Code Exchange) tercih edilmelidir. Lock kütüphanesi yapılandırmasında oidcConformant: true seçilerek modern standartlara uyum sağlanır.

2. Token Depolama Güvenliği (LocalStorage vs In-Memory)

Token’ların LocalStorage içerisinde saklanması, uygulamanızda oluşabilecek bir Cross-Site Scripting (XSS) zafiyeti durumunda token’ın çalınma riskini doğurur. En güvenli yaklaşım:

  • Token’ları belekte (In-Memory) tutmak ve sayfa yenilendiğinde Auth0 Silent Authentication (Sessiz Kimlik Doğrulama) ile token’ı arka planda yenilemektir.
  • Refresh Token kullanılıyorsa, Auth0 Dashboard üzerinden Refresh Token Rotation özelliğinin aktif edilmesi önerilir.

3. Content Security Policy (CSP)

Uygulamanızın HTML yapısına katı CSP kuralları ekleyerek dışarıdan zararlı betiklerin yürütülmesi engellenmelidir. Auth0 etki alanına (domain) ve Lock kaynaklarına CSP başlıklarında izin verilmelidir.

10. Karşılaşılan Yaygın Sorunlar ve Çözümleri

CORS (Cross-Origin Resource Sharing) Hataları

Eğer konsolda Origin http://localhost:4200 is not allowed şeklinde bir hata alıyorsanız, Auth0 Dashboard üzerindeki uygulamanızın Allowed Web Origins ve Allowed Callback URLs alanlarını kontrol etmelisiniz. Bu alanlarda adres sonunda taksim işareti (/) bulunmamasına dikkat edilmelidir.

Lock Ekranı Yüklenmiyor veya Açılmıyor

Auth0 Client ID veya Domain bilgilerinin yanlış yazılması veya tırnak işaretleri arasında boşluk kalması durumunda Lock başlatılamaz. Ayrıca, tarayıcıda çalışmayı engelleyen bir reklam engelleyici (AdBlocker) olup olmadığı kontrol edilmelidir.

JWT Token İmzası Doğrulama Hatası

Backend servisinize gönderdiğiniz Access Token kabul edilmiyorsa, Auth0 Dashboard üzerinde oluşturulan API’nizin Identifier (Audience) değeri ile Angular uygulamanızdaki audience parametresinin birebir eşleştiğinden emin olun.

11. Sonuç

Angular ve Auth0 Lock kombinasyonu, modern web uygulamaları için son derece güvenli, hızlı entegre edilebilir ve esnek bir kimlik doğrulama çözümü sunar. Geliştiricileri karmaşık güvenlik protokollerini baştan yazma zorunluluğundan kurtarırken, kullanıcılara sorunsuz ve şık bir giriş deneyimi sağlar.

Bu rehberde kapsanan AuthService mimarisi, HTTP Interceptor kullanımı, Route Guard koruması ve güvenlik en iyi uygulamaları sayesinde, Angular projelerinizde kurumsal seviyede bir kimlik doğrulama altyapısını güvenle kurgulayabilirsiniz. Projenizin büyüklüğüne bağlı olarak rolled-based access control (RBAC) ve multi-factor authentication (MFA) gibi ek Auth0 özelliklerini de bu mimariye kolayca entegre edebilirsiniz.

Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.
Yorum Yaz

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.