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:
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:
Yanıt Modeli — HvlResponse<Boolean>#
| Alan | Tip | Açıklama |
|---|---|---|
data | Boolean | Doğrulama başarılı ise true. |
Örnek Yanıt (Başarılı):
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:
- Redis: OTP kodları Redis üzerinde TTL ile saklanır. Redis bağlantısı yapılandırılmış olmalıdır.
- Kafka: OTP kodları Mail veya SMS bildirim kanallarına Kafka üzerinden iletilir. İlgili topic'lerin oluşturulmuş olması gerekmektedir.
- Bildirim Servisi: Mail veya SMS kanalını dinleyen bir bildirim servisi (Notification) çalışır durumda olmalıdır.
- Keysis Authorization Servisi: OTP uçları Keysis authorization servisi (
hvl-oauth-authz-starter) üzerinden sunulmaktadır.