Ana içeriğe geç

1.6.6. OTP Verification Provider#

OTP (One-Time Password) Verification Provider, Keysis altyapısı üzerinden tek kullanımlık doğrulama kodu üretimi ve doğrulaması hizmeti sunar. Üretilen kodlar e-posta veya SMS kanalları üzerinden kullanıcıya iletilir; doğrulama işlemi referans kimliği ile gerçekleştirilir.

Kodlar Redis üzerinde TTL ile saklanır, belirli deneme sayısını aştığında otomatik olarak geçersiz kılınır.

Önemli

OTP kodu hiçbir zaman HTTP yanıtında döndürülmez. Kod yalnızca Kafka bildirim kanalı (MAIL veya SMS) üzerinden alıcıya iletilir.


Genel Akış#

sequenceDiagram
    participant İstemci as İstemci Uygulama
    participant Keysis as Keysis OTP Servisi
    participant Redis as Redis Cache
    participant Kafka as Kafka Notification

    İstemci->>Keysis: POST /otp/generate
    Keysis->>Keysis: Kod üretimi (SecureRandom)
    Keysis->>Redis: Kod + referenceId kaydet (TTL)
    Keysis->>Kafka: Bildirim gönder (MAIL/SMS)
    Keysis-->>İstemci: referenceId, maskedReceiver, expirationDate

    Note over İstemci: Kullanıcı kodu alır (e-posta/SMS)

    İstemci->>Keysis: POST /otp/verify (referenceId + code)
    Keysis->>Redis: referenceId ile kod sorgula
    Keysis->>Keysis: Kod karşılaştır
    Keysis-->>İstemci: true / false

İstemci Bağımlılığı#

OTP servisini Feign Client üzerinden kullanabilmek için projenize aşağıdaki bağımlılığı eklemeniz gerekmektedir.

Gradle Bağımlılıkları

dependencyManagement {
    imports {
        mavenBom "tr.com.havelsan.framework.system:hvl-oauth-parent"
    }
}

compile (
    [group: 'tr.com.havelsan.framework.oauth.cloud' , name: 'hvl-oauth-authz-cloud-client']
)

Feign Client Aktivasyonu#

Feign client uçlarını kullanabilmek için configuration bean'ine aşağıdaki annotation eklenmelidir.


Rest Servis Tanımı#

OTP servisi HvlAuthzOtpRestService Feign Client arayüzü üzerinden iki adet uç sunmaktadır.

Servis Kullanımı

@Service
@RequiredArgsConstructor
public class MyOtpService {

    private final HvlAuthzOtpRestService hvlAuthzOtpRestService;

    public HvlOAuthOtpGenerationResponseModel generateOtp(HvlOAuthOtpChannel channel, String receiver) {
        HvlOAuthOtpGenerationRequestModel request = new HvlOAuthOtpGenerationRequestModel();
        request.setChannel(channel);
        request.setReceiver(receiver);
        HvlResponse<HvlOAuthOtpGenerationResponseModel> response = hvlAuthzOtpRestService.generate(request);
        return response.getData();
    }

    public boolean verifyOtp(String referenceId, String code) {
        HvlOAuthOtpVerificationRequestModel request = new HvlOAuthOtpVerificationRequestModel();
        request.setReferenceId(referenceId);
        request.setCode(code);
        HvlResponse<Boolean> response = hvlAuthzOtpRestService.verify(request);
        return response.getData();
    }
}
HvlAuthzOtpRestService.java

@Validated
@HvlPublicFeignRestService
@FeignClient(name = "${hvl.oauth.authz.otp.service.name:otpRestService}",
             path = "${hvl.oauth.authz.otp.service.path:/otp}",
             url = "${hvl.oauth.authz.otp.service.url:${hvl.oauth.authz.service.url}}")
public interface HvlAuthzOtpRestService {

    @PostMapping(value = "/generate",
                 consumes = MediaType.APPLICATION_JSON_VALUE,
                 produces = MediaType.APPLICATION_JSON_VALUE)
    HvlResponse<HvlOAuthOtpGenerationResponseModel> generate(
            @NotNull @Valid @RequestBody HvlOAuthOtpGenerationRequestModel otpGenerationRequestModel);

    @PostMapping(value = "/verify",
                 consumes = MediaType.APPLICATION_JSON_VALUE,
                 produces = MediaType.APPLICATION_JSON_VALUE)
    HvlResponse<Boolean> verify(
            @NotNull @Valid @RequestBody HvlOAuthOtpVerificationRequestModel otpVerificationRequestModel);
}


REST API Uçları#

POST /otp/generate#

Tek kullanımlık doğrulama kodu üretir ve belirtilen kanal (MAIL veya SMS) üzerinden alıcıya iletir.

İstek Modeli — HvlOAuthOtpGenerationRequestModel#

Alan Tip Zorunlu Açıklama
channel HvlOAuthOtpChannel Evet Kodun iletileceği kanal. MAIL veya SMS değerini alır.
receiver String Hayır Doğrudan alıcı adresi (e-posta veya telefon numarası). Boş bırakıldığında userDetailIntegrationCode üzerinden çözümlenir.
userDetailIntegrationCode String Hayır receiver boş olduğunda, kullanıcının profil detayından (e-posta veya cep telefonu) alıcı bilgisini çözmek için kullanılır.
language String Hayır Bildirim şablon dili (ör. tr, en). Belirtilmezse sistem dili kullanılır.

Dikkat

receiver ve userDetailIntegrationCode alanlarından en az biri sağlanmalıdır. Her ikisi de boş bırakılırsa alıcı çözümlenemez.

Örnek İstek:

{
  "channel": "MAIL",
  "receiver": "kullanici@example.com",
  "language": "tr"
}

Yanıt Modeli — HvlOAuthOtpGenerationResponseModel#

Alan Tip Açıklama
referenceId String Üretilen OTP kodunun benzersiz referans kimliği (UUID). Doğrulama işleminde bu değer kullanılır.
channel HvlOAuthOtpChannel Kullanılan kanal (MAIL veya SMS).
maskedReceiver String Maskelenmiş alıcı adresi (ör. ***ci@example.com veya *********12).
expirationMinutesTtl long Kodun geçerlilik süresi (dakika). Varsayılan: 3.
expirationDate OffsetDateTime Kodun son geçerlilik tarihi.

Örnek Yanıt:

{
  "data": {
    "referenceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "channel": "MAIL",
    "maskedReceiver": "***ci@example.com",
    "expirationMinutesTtl": 3,
    "expirationDate": "2026-09-10T15:40:00+03:00"
  },
  "errors": null,
  "warnings": null
}

POST /otp/verify#

Üretilmiş OTP kodunu referans kimliği ile doğrular.

İstek Modeli — HvlOAuthOtpVerificationRequestModel#

Alan Tip Zorunlu Açıklama
referenceId String Evet Generate yanıtından alınan benzersiz referans kimliği.
code String Evet Kullanıcının e-posta veya SMS ile aldığı doğrulama kodu.

Örnek İstek:

{
  "referenceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "code": "482916"
}

Yanıt Modeli — HvlResponse<Boolean>#

Alan Tip Açıklama
data Boolean Doğrulama başarılı ise true.

Örnek Yanıt (Başarılı):

{
  "data": true,
  "errors": null,
  "warnings": null
}

Kanal Tipleri — HvlOAuthOtpChannel#

Değer Açıklama
MAIL OTP kodu e-posta bildirimi ile iletilir.
SMS OTP kodu SMS bildirimi ile iletilir.

Hata Kodları#

Doğrulama sırasında aşağıdaki hata durumları oluşabilir:

Hata Kodu Açıklama
OAUTH-OTP_0002 OTP kodu süresi dolmuş veya bulunamadı.
OAUTH-OTP_0003 Girilen OTP kodu geçersiz. Deneme sayacı artırılır.
OAUTH-OTP_0004 Maksimum doğrulama deneme sayısı aşıldı. Kod otomatik olarak geçersiz kılınır.

Yapılandırma Parametreleri#

OTP servisinin sunucu tarafı yapılandırması aşağıdaki parametreler ile kontrol edilir:

Parametre Ortam Değişkeni Varsayılan Açıklama
hvl.oauth.otp.verification.enabled OTP_VERIFICATION_ENABLED true OTP doğrulama özelliğini etkinleştirir/devre dışı bırakır.
hvl.oauth.otp.verification.code-length OTP_VERIFICATION_CODE_LENGTH 6 Üretilecek OTP kodunun karakter uzunluğu.
hvl.oauth.otp.verification.expiration-minutes-ttl OTP_VERIFICATION_EXPIRATION_MINUTES_TTL 3 Kodun geçerlilik süresi (dakika).
hvl.oauth.otp.verification.max-verification-attempt-count OTP_VERIFICATION_MAX_ATTEMPT_COUNT 3 Maksimum doğrulama deneme sayısı. Aşıldığında kod silinir.
hvl.oauth.otp.verification.mail-event-topic-name OTP_MAIL_EVENT_TOPIC javalt-oauth-mail-notification E-posta bildirimleri için Kafka topic adı.
hvl.oauth.otp.verification.sms-event-topic-name OTP_SMS_EVENT_TOPIC javalt-oauth-sms-notification SMS bildirimleri için Kafka topic adı.
hvl.oauth.otp.verification.mail-template-code OTP_MAIL_TEMPLATE_CODE HVL_OAUTH_OTP_VERIFICATION_001 E-posta bildirim şablon kodu.
hvl.oauth.otp.verification.sms-template-code OTP_SMS_TEMPLATE_CODE HVL_OAUTH_OTP_VERIFICATION_001 SMS bildirim şablon kodu.

İstemci Tarafı Yapılandırması#

İstemci uygulamanın application.yml dosyasında Feign Client bağlantı ayarları:

hvl:
  oauth:
    authz:
      service:
        url: http://localhost:9190
      otp:
        service:
          name: otpRestService
          path: /otp
          url: ${hvl.oauth.authz.service.url}

Ön Koşullar#

OTP servisinin düzgün çalışabilmesi için aşağıdaki altyapı bileşenlerinin hazır olması gerekmektedir:

  1. Redis: OTP kodları Redis üzerinde TTL ile saklanır. Redis bağlantısı yapılandırılmış olmalıdır.
  2. Kafka: OTP kodları Mail veya SMS bildirim kanallarına Kafka üzerinden iletilir. İlgili topic'lerin oluşturulmuş olması gerekmektedir.
  3. Bildirim Servisi: Mail veya SMS kanalını dinleyen bir bildirim servisi (Notification) çalışır durumda olmalıdır.
  4. Keysis Authorization Servisi: OTP uçları Keysis authorization servisi (hvl-oauth-authz-starter) üzerinden sunulmaktadır.