ErtisAuth

Harici Kimlik Sağlayıcılar

Google, Apple, Facebook ve Microsoft ile giriş.

Kullanıcılar Google, Apple, Facebook ya da Microsoft'ta zaten sahip oldukları bir hesapla giriş yapabilir. İstemci uygulamanız sağlayıcının kendi giriş akışını (SDK'sını ya da web akışını) çalıştırır ve sonucu ErtisAuth'a gönderir; ErtisAuth sonucu sağlayıcıya doğrulatır ve tıpkı şifreyle girişte olduğu gibi bir ErtisAuth token çifti döner.

akış
Uygulama ──(1) sağlayıcı girişi──▶ Google / Apple / Facebook / Microsoft
    │                                          │
    │◀──────────(2) sağlayıcı token'ı ─────────┘
    │
    └──(3) POST /oauth/{slug}/login ──▶ ErtisAuth ──(4) doğrula─▶ sağlayıcı
                                           │
    ◀──────────(5) ErtisAuth token'ları ───┘

İlk girişte kullanıcı oluşturulur; sonraki girişler aynı kullanıcıyı yeniden bulur.

Desteklenen sağlayıcılar#

typeİstemcinin gönderdiğiErtisAuth'un doğrulama şekli
GoogleGoogle ID token'ıToken'ın imzasını ve audience değerini Google ile doğrular
FacebookFacebook access token'ıToken'ı Facebook Graph API'sine sorar ve profili oradan okur
Limited Login ile FacebookLimited Login JWT'siJWT'yi Facebook'un anahtarlarıyla doğrular
MicrosoftMicrosoft Graph için bir Microsoft access token'ıToken ile profili Microsoft Graph'tan okur
AppleWeb'de Sign in with Apple'ın authorization code'uKodu Apple ile değiştirir ve kimliği Apple'ın ID token'ından okur
AppleNativeYerel bir iOS/macOS uygulamasında Sign in with Apple'ın authorization code'uApple ile aynı; client id olarak uygulamanın bundle id'si kullanılır

Kimlik (sağlayıcıdaki kullanıcı id'si, e-posta adresi) her zaman ErtisAuth'un sağlayıcıdan aldığı veriden alınır; istemcinin iddia ettiğinden asla alınmaz. İstemcinin gönderdiği adlar yalnızca sağlayıcının bunları yalnızca istemciyle paylaştığı durumlarda kullanılır (Apple kullanıcının adını yalnızca bir kez, uygulamaya gönderir).

Sağlayıcı nesnesi#

json
{
	"_id": "66f1c0d2a4b5c6d7e8f90180",
	"type": "Google",
	"name": "Google",
	"slug": "google",
	"description": "Sign in with Google for the web app",
	"defaultRole": "customer",
	"defaultUserType": "customer",
	"appClientId": "1234567890-abc.apps.googleusercontent.com",
	"isActive": true,
	"trust_email": false,
	"membership_id": "66f1c0d2a4b5c6d7e8f90123"
}
AlanZorunluAçıklama
typeevetGoogle, Facebook, Microsoft, Apple ya da AppleNative. Sonradan değiştirilemez.
namehayırGörünen ad. Varsayılan olarak tip.
slughayırMembership içinde benzersizdir; varsayılan olarak ad. Sonradan değiştirilemez: sağlayıcının giriş URL'sidir (/oauth/{slug}/login) ve kullanıcıların bağlı hesaplarında saklanır.
descriptionhayır
isActivehayırAktif olmayan sağlayıcılar girişleri reddeder (403 ProviderIsDisable). Varsayılan olarak false.
defaultRoleaktifseBu sağlayıcının oluşturduğu kullanıcılara verilen rolün slug'ı.
defaultUserTypeaktifseBu sağlayıcının oluşturduğu kullanıcılara verilen kullanıcı tipinin slug'ı.
appClientIdaktifseUygulamanızın sağlayıcıdaki client id'si: Google OAuth client id'si, Facebook app id'si, Microsoft application (client) id'si ya da Apple Services ID (Apple) / bundle id (AppleNative).
tenantIdhayırMicrosoft: Microsoft Entra tenant id'niz.
teamId, privateKeyId, privateKeyApple tipleriApple Developer team id'niz, bir Sign in with Apple anahtarının key id'si ve anahtarın kendisi (.p8 dosyasının içeriği).
redirectUriApple tipleriServices ID'niz için kayıtlı redirect URI; istemcinin kullandığıyla aynı.
trust_emailhayırBkz. Hesap bağlama. Varsayılan olarak false.

Aynı tipte birden fazla sağlayıcı oluşturabilirsiniz; örneğin her uygulama için kendi client id'si ve kendi slug'ı olan bir Google sağlayıcısı.

Varsayılan kullanıcı tipi, sağlayıcının doldurduğu alanlara (firstname, lastname, email_address, username) izin vermelidir. Kullanıcı tipi avatar adında bir object alanı tanımlıyorsa sağlayıcının profil resmi URL'si avatar.url alanında saklanır.

Giriş yapma#

http
POST /oauth/{slug}/login
X-Ertis-Alias: <membership_id>
Content-Type: application/json
HeaderZorunluAçıklama
X-Ertis-AliasevetMembership id'si
X-IpAddress, X-UserAgenthayırŞifreyle girişte olduğu gibi oturumla birlikte saklanır

Token gerekmez. Gövde, sağlayıcının tipine göre değişir.

Google#

json
{
	"clientId": "1234567890-abc.apps.googleusercontent.com",
	"token": {
		"idToken": "eyJhbGciOiJSUzI1NiIs…"
	}
}

ID token, sağlayıcının appClientId değeri için üretilmiş olmalı ve kullanıcının e-postasını ve adını içermelidir: openid email profile scope'larını isteyin. Bunları içermeyen bir token 401 ProviderProfileIncomplete döner.

Facebook#

json
{
	"appId": "<facebook_app_id>",
	"user": {
		"id": "<facebook_user_id>",
		"first_name": "Ada",
		"last_name": "Lovelace",
		"email": "ada@example.com",
		"accessToken": "<facebook_access_token>"
	}
}

appId, sağlayıcının appClientId değeri olmalıdır. Gövdede id, first_name, email ve accessToken zorunludur; ama ErtisAuth'un kullandığı kimlik ve e-posta adresi access token ile Facebook'tan okunur. Facebook Limited Login (iOS) için URL'ye ?limited_flow=true ekleyin ve Limited Login authentication token'ını accessToken olarak gönderin.

Microsoft#

json
{
	"clientId": "<application_client_id>",
	"token": {
		"accessToken": "<access_token_for_microsoft_graph>"
	}
}

Access token, Microsoft Graph için geçerli olmalıdır (User.Read).

Apple ve AppleNative#

json
{
	"authorization": {
		"code": "<authorization_code>",
		"id_token": "<id_token>"
	},
	"user": {
		"name": { "firstName": "Ada", "lastName": "Lovelace" },
		"email": "ada@example.com"
	}
}

Bu, Sign in with Apple'ın olduğu gibi gönderilen yanıtıdır. user yalnızca kullanıcının ilk girişinde, Apple adı uygulamayla paylaştığında bulunur; elinizdeyse gönderin. ErtisAuth code değerini Apple ile değiştirir; bu yüzden bir kod yalnızca bir kez kullanılabilir ve birkaç dakika içinde süresi dolar.

Yanıt#

Şifreyle girişte olduğu gibi bir ErtisAuth token çiftiyle 201 Created.

Hatalar#

DurumKodNe zaman
400MembershipIdRequiredX-Ertis-Alias eksik
400InvalidProviderLoginRequestGövde, sağlayıcının tipi için geçerli bir giriş sonucu değil
401UnauthorizedSağlayıcı token'ı ya da kodu kabul etmedi
401ProviderProfileIncompleteSağlayıcı profilinde e-posta adresi ya da ad eksik
401UserInactiveEşleşen kullanıcı aktif değil ya da dondurulmuş
403ProviderNotConfiguredBu slug'a sahip sağlayıcı yok
403ProviderIsDisableSağlayıcı aktif değil
403UntrustedProviderİstekteki client id, sağlayıcının client id'si değil
409ProviderEmailNotTrustedAynı e-postaya sahip bir kullanıcı var ve e-postaya güvenilemiyor (aşağıya bakın)
501ProviderNotConfiguredCorrectlySağlayıcının yapılandırması eksik ya da hatalı (ör. okunamayan bir Apple anahtarı)
503ProviderUnavailableSağlayıcıya ulaşılamadı; daha sonra tekrar deneyin

Kullanıcılar nasıl eşleştirilir#

  1. Bağlı hesapla. Her kullanıcı giriş yaptığı hesapları connected_accounts alanında tutar:
    json
    "connected_accounts": [
    	{ "provider": "Google", "slug": "google", "user_id": "109876543210987654321" }
    ]
    Bir giriş, bağlı hesabı aynı sağlayıcı tipine ve aynı sağlayıcı kullanıcı id'sine sahip kullanıcıyı bulur.
  2. E-posta adresiyle. Hiçbir bağlı hesap eşleşmezse ErtisAuth membership içinde aynı e-posta adresine sahip bir kullanıcı arar ve sağlayıcı hesabını ona bağlar; aşağıya bakın.
  3. Kayıt. Hiçbir kullanıcı eşleşmezse sağlayıcının defaultRole ve defaultUserType değerleriyle, sağlayıcıdan gelen ad ve e-postayla, username olarak e-posta adresiyle ve source_provider alanı sağlayıcının tipi olacak şekilde yeni bir kullanıcı oluşturulur. Bu kullanıcının şifresi yoktur ve sağlayıcı üzerinden giriş yapar.

Her giriş bir TokenGenerated olayı kaydeder; kayıt ayrıca UserCreated kaydeder.

Mevcut hesaplara bağlama#

Bir sağlayıcı hesabını e-posta adresiyle mevcut bir kullanıcıya bağlamak, ancak sağlayıcı kullanıcının o adrese sahip olduğunu garanti ediyorsa güvenlidir. Aksi halde herkes başka birinin e-posta adresiyle bir sağlayıcı hesabı açıp onun ErtisAuth hesabını ele geçirebilirdi.

SağlayıcıE-postayla bağlanır
GoogleGoogle e-postayı doğrulanmış olarak bildirdiğinde
Apple, AppleNativeApple e-postayı doğrulanmış olarak bildirdiğinde
Facebookyalnızca sağlayıcıda trust_email: true olduğunda
Microsoftyalnızca sağlayıcıda trust_email: true olduğunda

Aynı e-posta adresine sahip mevcut bir kullanıcı varsa ve e-postaya güvenilemiyorsa giriş 409 ProviderEmailNotTrusted ile reddedilir. Kullanıcı şifresiyle giriş yapabilir; ardından hesabı bağlamasına izin verebilirsiniz.

Uyarı: trust_email değerini yalnızca sağlayıcının e-posta adresini doğrulamamış olabileceğini kabul ediyorsanız true yapın. Microsoft'ta mail özniteliğini kullanıcının kurumu yönetir ve Microsoft tarafından doğrulanmaz.

Hesap aktivasyonu#

Membership aktivasyon istiyorsa, sağlayıcıyla kayıt olan kullanıcılar da diğer kullanıcılar gibi aktif olmadan oluşturulur ve hook kuruluysa aktivasyon e-postasını alır.

Çıkış yapma#

Bir ErtisAuth token'ını iptal etmek, sağlayıcı destekliyorsa kullanıcının bağlı hesabıyla birlikte saklanan sağlayıcı token'ını da iptal eder.

Sağlayıcıları yönetme#

Tüm route'lar /memberships/{membershipId} altındadır.

MetotRouteAçıklamaYetki
GET/providers/{id}Bir sağlayıcıyı alma (id ya da slug)providers.read.{id}
GET/providersMembership'in sağlayıcılarını listelemeproviders.read
GET/providers/active-providersAktif sağlayıcıların herkese açık ayarlarıyok
POST/providersSağlayıcı oluşturmaproviders.create
PUT/providers/{id}Sağlayıcı güncellemeproviders.update.{id}
DELETE/providers/{id}Sağlayıcı silmeproviders.delete.{id}

Aktif sağlayıcılar#

GET /memberships/{membershipId}/providers/active-providers herkese açıktır; böylece giriş sayfaları doğru butonları gösterebilir. Yalnızca herkese açık ayarları döner:

json
[
	{ "_id": "…", "name": "Google", "slug": "google", "type": "Google", "appClientId": "1234567890-abc.apps.googleusercontent.com", "membership_id": "…" },
	{ "_id": "…", "name": "Apple", "slug": "apple", "type": "Apple", "appClientId": "com.example.web", "redirectUri": "https://app.example.com/auth/apple", "membership_id": "…" },
	{ "_id": "…", "name": "Microsoft", "slug": "microsoft", "type": "Microsoft", "appClientId": "…", "tenantId": "…", "membership_id": "…" }
]

Sağlayıcı oluşturma#

shell
curl -X POST https://auth.example.com/memberships/<membership_id>/providers \
	-H 'Authorization: Bearer <access_token>' \
	-H 'Content-Type: application/json' \
	-d '{
		"type": "Apple",
		"name": "Sign in with Apple",
		"slug": "apple",
		"defaultRole": "customer",
		"defaultUserType": "customer",
		"appClientId": "com.example.web",
		"teamId": "ABCDE12345",
		"privateKeyId": "XYZ987WVU6",
		"privateKey": "-----BEGIN PRIVATE KEY-----\nMIGTAgEAMBMG…\n-----END PRIVATE KEY-----",
		"redirectUri": "https://app.example.com/auth/apple",
		"isActive": true
	}'

Yanıt 201 Created: sağlayıcı.

HataNe zaman
400 ProviderTypeRequired, 400 UnknownProvider, 400 UnsupportedProvidertype eksik ya da bilinmiyor
400 ModelValidationErrorAktif bir sağlayıcıda zorunlu bir ayar eksik
409 ProviderAlreadyExistsSlug zaten kullanılıyor

Sağlayıcı güncelleme#

http
PUT /memberships/{membershipId}/providers/{id}

Gönderilmeyen alanlar mevcut değerlerini korur. type değişemez; farklı bir slug 400 ProviderSlugCannotBeChanged döner. Hiçbir değişiklik içermeyen bir güncelleme 409 IdenticalDocumentError döner.

Sağlayıcı silme#

http
DELETE /memberships/{membershipId}/providers/{id}

Yanıt 204 No Content. Sağlayıcının oluşturduğu kullanıcılar hesaplarını korur.

Olaylar#

ProviderCreated, ProviderUpdated ve ProviderDeleted. Bkz. Olaylar.

Dokümantasyonda bir hata mı buldunuz? Issue açın