Hesap Kurtarma ve Aktivasyon
Aktivasyon e-postaları, şifre sıfırlama ve tek kullanımlık şifreler.
Bu sayfa, kullanıcıların e-posta adreslerinin kendilerine ait olduğunu kanıtlamalarını ve hesaplarına geri dönmelerini sağlayan akışları anlatır:
- Hesap aktivasyonu: yeni kullanıcılar giriş yapabilmeden önce e-posta adreslerini onaylar.
- Şifre sıfırlama: şifresini unutan kullanıcılar e-postayla bir sıfırlama bağlantısı alır.
- Tek kullanımlık şifreler: kullanıcılar sizin seçtiğiniz bir kanaldan (SMS, çağrı merkezi…) kısa bir kod alır ve bunu bir şifre sıfırlamayla değiştirir.
Üçü de ErtisAuth'u çağıran, size ait bir sayfa (bir aktivasyon sayfası, bir şifre sıfırlama sayfası) ve onun backend'i ile sona erer. ErtisAuth bu sayfaları barındırmaz.
Bağlantılar nasıl çalışır#
Aktivasyon ve sıfırlama e-postaları sayfanıza bir bağlantı içerir. Sayfanın URL'sini X-Host header'ında verirsiniz; ErtisAuth da buna kod içeren bir query parametresi ekler:
| Akış | Bağlantı |
|---|---|
| Aktivasyon | {X-Host}?uat=<code> |
| Şifre sıfırlama | {X-Host}?rpt=<code> |
Örneğin X-Host: https://app.example.com/reset-password ile sıfırlama e-postası https://app.example.com/reset-password?rpt=NjZmMWMw… adresine bağlantı verir.
Kod, <membership_id>:<token> değerinin base64 halidir. Onu opak bir değer olarak ele alın: sayfanız kodu query string'den okur ve ErtisAuth'a değiştirmeden geri gönderir.
Kodlar tek kullanımlık ve kısa ömürlüdür; access token olarak kullanılamazlar.
Bu endpoint'leri kim çağırır#
Sayfanızdaki kişi giriş yapmamış olduğu için bu akışların endpoint'leri diğer endpoint'ler gibi korunur (yetkiler aşağıda). Onları sayfanızın backend'inden, bir uygulamanın Basic token'ıyla çağırın ve o uygulamanın rolüne yalnızca akışların ihtiyaç duyduğunu verin:
{
"name": "Account Pages",
"slug": "account-pages",
"permissions": [ "users.read", "users.update", "users.create" ]
}Uygulamanın secret'ını asla tarayıcıya koymayın.
Hesap aktivasyonu#
Bir membership'in user_activation değeri active olduğunda yeni kullanıcılar aktif olmadan oluşturulur ve aktivasyon e-postalarındaki bağlantıya tıklayana kadar giriş yapamazlar (401 UserInactive).
Kurulum#
- Membership'e bir mail sağlayıcısı ekleyin (
mail_providers; bkz. Membership'ler). - Adı tam olarak
User Activationolan,UserCreatedolayı için veactivedurumunda bir mail hook oluşturun. Şablonunda{{activationLink}}kullanın:Şablon{ "name": "User Activation", "event": "UserCreated", "status": "active", "mailProvider": "company-smtp", "fromName": "My Company", "fromAddress": "no-reply@example.com", "sendToUtilizer": false, "recipients": [ { "displayName": "{{user.firstname}}", "emailAddress": "{{user.email_address}}" } ], "mailSubject": "Activate your account", "mailTemplate": "<p>Hi {{user.firstname}},</p><p><a href=\"{{activationLink}}\">Activate your account</a></p>" }user(yeni kullanıcı) veactivationLinkdeğerlerini alır. - Membership'te
user_activationdeğeriniactiveyapın.
Mail sağlayıcısı ya da aktivasyon mail hook'u olmadan kullanıcı oluşturma, hiçbir şey oluşturulmadan 501 NotDefinedAnyMailProvider ya da 501 ActivationMailHookWasNotDefined ile başarısız olur.
Akış#
- Kullanıcıyı
X-Hostheader'ı aktivasyon sayfanızı gösterecek şekilde oluşturun:Kullanıcı aktif olmadan oluşturulur ve aktivasyon e-postası kuyruğa alınır.POST /memberships/{membershipId}/users X-Host: https://app.example.com/activateX-Hosteksikse kullanıcı yine oluşturulur ama e-posta gönderilmez; e-postayı daha sonra yeniden gönderin. - Kullanıcı bağlantıya tıklar ve
https://app.example.com/activate?uat=<code>adresine gelir. - Backend'iniz hesabı aktifleştirir:Yetki:
GET /memberships/{membershipId}/users/activation?uat=<code> Authorization: Basic <application_id>:<secret>users.update. Yanıt200 OK, aktifleştirilen kullanıcıyla birlikte.
Aktivasyon kodu 72 saat geçerlidir ve yalnızca bir kez kullanılabilir. Kullanıcı bu arada değiştirilirse, örneğin dondurulursa, kod da çalışmaz hale gelir.
| Hata | Ne zaman |
|---|---|
401 InvalidToken | Kod hatalı biçimde, süresi dolmuş, zaten kullanılmış ya da başka bir membership'e ait |
400 UserAlreadyActive | Kullanıcı zaten aktif |
Aktivasyon e-postasını yeniden gönderme#
POST /memberships/{membershipId}/users/resend-activation-mail
X-Host: https://app.example.com/activate
Content-Type: application/json
{ "email_address": "ada@example.com" }Yetki: users.create. Yanıt 200 OK:
{ "emailAddress": "ada@example.com" }| Hata | Ne zaman |
|---|---|
400 HostRequired, 400 EmailAddressRequired | Zorunlu bir değer eksik |
400 UserAlreadyActive | Aktifleştirilecek bir şey yok |
404 UserNotFound | Bu e-posta adresine sahip kullanıcı yok |
501 NotDefinedAnyMailProvider, 501 ActivationMailHookWasNotDefined | E-posta gönderilemiyor |
E-posta olmadan aktifleştirme#
Bir yönetici bir kullanıcıyı GET /users/{id}/activate ile doğrudan aktifleştirebilir.
Şifre sıfırlama#
Kurulum#
- Membership'e bir mail sağlayıcısı ekleyin.
- Adı tam olarak
Reset Passwordolan,UserPasswordResetolayı için veactivedurumunda bir mail hook oluşturun. Şablonunda{{resetPasswordLink}}kullanın:Şablon{ "name": "Reset Password", "event": "UserPasswordReset", "status": "active", "mailProvider": "company-smtp", "fromName": "My Company", "fromAddress": "no-reply@example.com", "recipients": [ { "displayName": "{{user.firstname}}", "emailAddress": "{{user.email_address}}" } ], "mailSubject": "Reset your password", "mailTemplate": "<p>Hi {{user.firstname}},</p><p><a href=\"{{resetPasswordLink}}\">Choose a new password</a>. The link expires soon.</p>" }userveresetPasswordLinkdeğerlerini alır. - İsterseniz membership'te
reset_password_token_expires_indeğerini ayarlayın (varsayılan olarak 2 saat).
1. Sıfırlamayı isteyin#
"Şifremi unuttum" sayfanızın backend'i şunu çağırır:
POST /memberships/{membershipId}/users/reset-password
Authorization: Basic <application_id>:<secret>
X-Host: https://app.example.com/reset-password
Content-Type: application/json
{ "email_address": "ada@example.com" }Yetki: users.update. Yanıt 200 OK:
{
"message": "Reset token generated",
"expiresIn": 7200
}E-posta kuyruğa alınır ve bir UserPasswordReset olayı kaydedilir.
| Hata | Ne zaman |
|---|---|
400 HostRequired, 400 EmailAddressRequired | Zorunlu bir değer eksik |
401 UserInactive | Hesap aktif değil ya da dondurulmuş: bu yolla kurtarılamaz |
404 UserNotFound | Bu e-posta adresine sahip kullanıcı yok |
501 NotDefinedAnyMailProvider, 501 ResetPasswordMailHookWasNotDefined | E-posta gönderilemiyor |
404 döner. Hangi adreslerin hesabı olduğunu açığa vurmamak için iki durumda da kişiye aynı mesajı gösterin ("Böyle bir hesap varsa size bir e-posta gönderdik").2. Bağlantıyı doğrulayın#
Kullanıcı https://app.example.com/reset-password?rpt=<code> adresini açtığında, formu göstermeden önce kodu kontrol edin:
GET /memberships/{membershipId}/users/verify-reset-token?token=<code>
Authorization: Basic <application_id>:<secret>Yetki: users.read. Yanıt 200 OK:
{ "email_address": "ada@example.com" }Geçersiz, süresi dolmuş ya da kullanılmış bir kod 401 InvalidToken döner.
3. Yeni şifreyi belirleyin#
POST /memberships/{membershipId}/users/set-password
Authorization: Basic <application_id>:<secret>
Content-Type: application/json
{
"email_address": "ada@example.com",
"reset_token": "<code>",
"password": "<new password>"
}email_address yerine username da gönderilebilir. Yetki: users.update. Yanıt 200 OK.
- Kod o kullanıcıya ait olmalıdır.
- Kod bir kez çalışır: şifreyi belirlemek onu geçersiz kılar.
- Kullanıcının tüm cihazlardaki oturumları kapanır.
- Bir
UserPasswordChangedolayı kaydedilir.
| Hata | Ne zaman |
|---|---|
400 ResetTokenRequired, 400 EmailAddressRequired, 400 PasswordRequired | Zorunlu bir değer eksik |
400 PasswordMinLengthRuleError | Şifre 6 karakterden kısa |
401 InvalidToken | Kod geçersiz, süresi dolmuş, kullanılmış ya da başka bir kullanıcıya ait |
Tek kullanımlık şifreler#
Tek kullanımlık şifreler (OTP), kullanıcıların hesaplarını e-posta olmadan kurtarmalarını sağlar: kısa bir kodu onlara kendiniz iletirsiniz, örneğin SMS ile ya da bir destek temsilcisi aracılığıyla; onlar da bu kodu bir şifre sıfırlamayla değiştirir.
Kurulum#
Membership'te otp_settings değerini ayarlayın:
"otp_settings": {
"host": "https://app.example.com/reset-password",
"policy": {
"length": 6,
"contains_letters": false,
"contains_digits": true,
"expires_in": 300,
"max_attempts": 5
}
}| Alan | Açıklama |
|---|---|
host | Zorunlu. Kullanıcıların kodlarını girdiği sayfanın adresi; doğrulama isteği aynı değeri X-Host header'ında göndermelidir. |
policy.length | Kodun karakter sayısı. |
policy.contains_letters, policy.contains_digits | Kodun karakter kümesi. |
policy.expires_in | Kodun ve kodun karşılığında verilen sıfırlama token'ının (doğrulamadan itibaren sayılan) geçerlilik süresi, saniye cinsinden. Verilmezse 2 saat. |
policy.max_attempts | Kod silinmeden önce izin verilen yanlış deneme sayısı. Varsayılan 5, en az 1. |
1. Bir kod üretin#
Backend'iniz (bir SMS servisi, bir destek aracı) bir kullanıcı için kod üretir:
GET /memberships/{membershipId}/users/{userId}/generate-otp
Authorization: Basic <application_id>:<secret>Yetki: otp.create.{userId} (users değil, otp kaynağı). Yanıt 200 OK:
{
"_id": "66f1c0d2a4b5c6d7e8f90150",
"user_id": "66f1c0d2a4b5c6d7e8f90127",
"email_address": "ada@example.com",
"username": "ada",
"password": "482913",
"expires_in": 300,
"created_at": "2026-01-01T12:00:00Z",
"expire_time": "2026-01-01T12:05:00Z",
"membership_id": "66f1c0d2a4b5c6d7e8f90123"
}password alanı koddur. Kodu kullanıcıya iletin. Yalnızca bu yanıtta döner: ErtisAuth yalnızca anahtarlı bir hash'ini saklar. Yeni bir kod üretmek, kullanıcının önceki kodlarını siler.
Bu noktada henüz bir sıfırlama token'ı yoktur: token yalnızca kullanıcı kodu doğruladığında üretilir. Böylece kodları üreten servis kimsenin şifresini kendisi değiştiremez; veritabanını okuyabilen biri de değiştiremez.
| Hata | Ne zaman |
|---|---|
400 OtpNotConfiguredYet, 400 OtpHostNotConfiguredYet | Membership'in OTP ayarları yok |
401 UserInactive | Hesap aktif değil ya da dondurulmuş |
404 UserNotFound | Bilinmeyen kullanıcı |
2. Kodu doğrulayın#
Kullanıcı sayfanızda username'ini (ya da e-posta adresini) ve kodu girer; sayfanız şunu çağırır:
POST /verify-otp
X-Ertis-Alias: <membership_id>
X-Host: https://app.example.com/reset-password
Content-Type: application/json
{
"username": "ada",
"password": "482913"
}Token gerekmez. X-Host, membership'in otp_settings.host değerine eşit olmalıdır. Kodlar büyük/küçük harf ayrımı yapılmadan karşılaştırılır.
Yanıt 200 OK: şu anda üretilen bir sıfırlama token'ı. Geçerlilik süresi (expires_in) bu andan itibaren başlar.
{
"reset_token": "NjZmMWMwZDJhNGI1YzZkN2U4ZjkwMTIzOmV5Smhi…",
"expires_in": 300,
"created_at": "2026-01-01T12:00:00Z"
}| Hata | Ne zaman |
|---|---|
400 OtpHostRequired | X-Host eksik |
401 OtpHostMismatch | X-Host, membership'in OTP host'u değil |
401 InvalidCredentials | Yanlış kod ya da bilinmeyen kullanıcı |
401 OtpExpired | Kod doğruydu ama süresi dolmuş |
401 UserInactive | Hesap, kod üretildikten sonra devre dışı bırakılmış ya da dondurulmuş |
Bir kod bir kez kullanılabilir: başarılı bir doğrulama onu siler; bu yüzden aynı kodu tekrar doğrulamak 401 InvalidCredentials döner. Sıfırlama token'ı süresi dolana ya da kullanılana kadar geçerli kalır; yeniden doğrulamaya gerek yoktur.
Her yanlış kod başarısız bir deneme sayılır; max_attempts kadar başarısız denemeden sonra kod silinir ve yenisinin üretilmesi gerekir.
3. Yeni şifreyi belirleyin#
Önceki adımdaki reset_token ile POST /users/set-password endpoint'ini çağırın.
Dokümantasyonda bir hata mı buldunuz? Issue açın