> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flextell.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# OpenID Connect

> Flextell OAuth 2.0 üzerine OpenID Connect (OIDC) katmanı sunar. id_token ile kullanıcı kimliğini doğrulayın, discovery URL'i ile uç noktaları otomatik keşfedin.

Flextell, OAuth 2.0 üzerine [OpenID Connect 1.0](https://openid.net/specs/openid-connect-core-1_0.html) katmanı sunar. OIDC sayesinde yalnızca API'ye erişim değil, **kullanıcının kimliğini doğrulama** (sign-in) akışı da kurabilirsiniz — Flextell'i bir "Sign in with Flextell" identity provider olarak kullanabilirsiniz.

<Note>
  OIDC akışı, standart [Authorization Code akışı](/authentication/authorization-code) ile **aynı** uçları kullanır. Tek yapmanız gereken `scope` parametresine `openid` eklemek ve dönen `id_token`'ı işlemek.
</Note>

## Temel farkları

| Düz OAuth 2.0                    | OIDC (OAuth 2.0 + `openid` scope)                                                        |
| -------------------------------- | ---------------------------------------------------------------------------------------- |
| `access_token` + `refresh_token` | `access_token` + `refresh_token` + **`id_token`**                                        |
| API'yi çağırmanın yetkisi        | + Kullanıcının **kim** olduğunun kanıtı                                                  |
| `/oauth/token`                   | Aynı + **`/oauth/userinfo`**, **`/oauth/jwks`**, **`/.well-known/openid-configuration`** |

## Discovery

Uçlarımızı kod tarafında sabitlemek yerine **discovery URL**'i çekerek dinamik olarak öğrenin:

```
GET https://dev.flextell.ai/.well-known/openid-configuration
```

### Örnek yanıt

```json theme={null}
{
  "issuer": "https://dev.flextell.ai",
  "authorization_endpoint": "https://dev.flextell.ai/oauth/authorize",
  "token_endpoint": "https://dev.flextell.ai/oauth/token",
  "userinfo_endpoint": "https://dev.flextell.ai/oauth/userinfo",
  "jwks_uri": "https://dev.flextell.ai/oauth/jwks",
  "end_session_endpoint": "https://dev.flextell.ai/oauth/logout",
  "response_types_supported": ["code"],
  "subject_types_supported": ["public"],
  "id_token_signing_alg_values_supported": ["RS256"],
  "scopes_supported": ["openid", "profile", "email", "phone", "..."],
  "code_challenge_methods_supported": ["plain", "S256"],
  "grant_types_supported": ["authorization_code", "refresh_token"]
}
```

<Tip>
  Çoğu OIDC kütüphanesi (örn. `openid-client` Node, `python-jose` + `authlib`, `AppAuth` iOS/Android) yalnızca `issuer` URL'ini verdiğinizde discovery'yi otomatik yapar. Uçları manuel yazmak yerine bu yolu tercih edin.
</Tip>

## `openid` scope'u ile yetki alma

Standart Authorization Code isteğine `openid` scope'unu ekleyin. Kullanıcı bilgilerini de almak istiyorsanız `profile`, `email`, `phone` scope'larını da ekleyebilirsiniz:

```
https://dev.flextell.ai/oauth/authorize
  ?response_type=code
  &client_id=SIZIN_CLIENT_ID
  &redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback
  &scope=openid%20profile%20email
  &state=RASTGELE_STRING
```

### Token yanıtı

`openid` scope'u talep edildiğinde `/oauth/token` yanıtına ekstra `id_token` alanı eklenir:

```json theme={null}
{
  "token_type": "Bearer",
  "expires_in": 1296000,
  "access_token": "eyJ0eXAiOiJKV1Q...",
  "refresh_token": "def502004d...",
  "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
}
```

## id\_token nedir?

`id_token` **RS256** ile imzalanmış bir JWT'dir. İçinde "bu access token'ı falanca kullanıcı aldı" ifadesinin imzalı kanıtı vardır.

### Örnek payload (decode edilmiş)

```json theme={null}
{
  "iss": "https://dev.flextell.ai",
  "aud": "SIZIN_CLIENT_ID",
  "sub": "42",
  "iat": 1713515400,
  "exp": 1713519000,
  "name": "Ayşe Yılmaz",
  "email": "ayse@example.com",
  "phone_number": "+905551234567"
}
```

### Alanlar

<ResponseField name="iss" type="string">
  Token'ı üreten kimlik sağlayıcı. Her zaman `https://dev.flextell.ai` veya production'da `https://app.flextell.ai`.
</ResponseField>

<ResponseField name="aud" type="string">
  Token'ın kimin için üretildiği — sizin `client_id`'niz. **Kabul etmeden önce mutlaka doğrulayın**; değilse token size ait değildir.
</ResponseField>

<ResponseField name="sub" type="string">
  Kullanıcının Flextell'deki kalıcı ID'si. Kendi veritabanınızdaki hesabı bağlamak için bu değeri saklayın. E-posta değişse bile `sub` değişmez.
</ResponseField>

<ResponseField name="iat" type="integer">
  Token'ın üretildiği Unix timestamp.
</ResponseField>

<ResponseField name="exp" type="integer">
  Token'ın geçerlilik süresinin sonu (Unix timestamp).
</ResponseField>

<ResponseField name="name" type="string">
  Kullanıcının ad soyadı (yalnızca `profile` scope'u talep edildiyse).
</ResponseField>

<ResponseField name="email" type="string">
  Kullanıcının e-posta adresi (yalnızca `email` scope'u talep edildiyse).
</ResponseField>

<ResponseField name="phone_number" type="string">
  Kullanıcının telefon numarası (yalnızca `phone` scope'u talep edildiyse).
</ResponseField>

### Scope → claim eşlemesi

| Scope     | Eklenen claim'ler |
| --------- | ----------------- |
| `openid`  | `sub` (zorunlu)   |
| `profile` | `name`            |
| `email`   | `email`           |
| `phone`   | `phone_number`    |

## id\_token doğrulama

Flextell'den gelen `id_token`'ı backend'inizde **mutlaka** doğrulamanız gerekir. Asla imza kontrol etmeden güvenmeyin:

<Steps>
  <Step title="JWKS uçtan genel anahtarı çekin">
    ```
    GET https://dev.flextell.ai/oauth/jwks
    ```

    Bu URL, RS256 doğrulaması için gereken RSA public key'leri JWK formatında döner. Kütüphaneniz bu anahtarı cache'leyebilir.
  </Step>

  <Step title="İmzayı RS256 ile doğrulayın">
    JWT'nin header'ı `{"alg": "RS256", "typ": "JWT"}` olmalıdır. Public key ile imza eşleşmiyorsa token'ı reddedin.
  </Step>

  <Step title="Claim'leri doğrulayın">
    * `iss` → `https://dev.flextell.ai` veya `https://app.flextell.ai` olmalı.
    * `aud` → sizin `client_id`'niz olmalı.
    * `exp` → şimdiki zamandan büyük olmalı (saat farkı için ±60 sn tolerans tipiktir).
    * `iat` → gelecek bir zaman olmamalı.
  </Step>
</Steps>

### Node.js (jose kütüphanesi) örneği

```js theme={null}
import { createRemoteJWKSet, jwtVerify } from "jose";

const JWKS = createRemoteJWKSet(new URL("https://dev.flextell.ai/oauth/jwks"));

const { payload } = await jwtVerify(idToken, JWKS, {
  issuer: "https://dev.flextell.ai",
  audience: process.env.FLEXTELL_CLIENT_ID,
});

// payload.sub → kullanıcı ID'si (kendi DB'nizde flextell_user_id olarak saklayın)
// payload.email, payload.name → profil bilgileri
```

## UserInfo endpoint'i

`id_token` içindeki claim'ler dışında, access token ile `/oauth/userinfo` endpoint'ine istek atarak aynı bilgileri canlı olarak sorgulayabilirsiniz. Kullanıcı daha sonra profil bilgilerini değiştirdiyse güncel hali burada döner:

```bash theme={null}
curl --request GET \
  --url https://dev.flextell.ai/oauth/userinfo \
  --header "Authorization: Bearer SIZIN_ACCESS_TOKEN"
```

### Yanıt

```json theme={null}
{
  "sub": "42",
  "name": "Ayşe Yılmaz",
  "email": "ayse@example.com",
  "phone_number": "+905551234567"
}
```

Dönen alanlar access token'da onaylanmış scope'lara göre filtrelenir. Örneğin token'da yalnızca `openid` varsa sadece `sub` döner.

## Logout (end\_session\_endpoint)

OIDC standart çıkış akışı için [Token İptali → OpenID Connect ile oturum sonlandırma](/authentication/revoke-tokens) sayfasına bakın.

## PKCE ile güvenli istemciler

SPA veya native mobil uygulamalar `client_secret` saklayamadığı için OIDC akışını **PKCE** (Proof Key for Code Exchange) ile kullanmalıdır. Detaylar: [PKCE Akışı](/authentication/pkce).

## Sık sorulanlar

**`id_token`'ı API isteklerinde Bearer olarak kullanabilir miyim?** Hayır. `id_token` kimlik kanıtıdır, yetki tokeni değildir. API'ye erişim için her zaman `access_token` kullanın.

**`id_token`'ı yenileyebilir miyim?** Evet. Refresh token ile yeni bir access token aldığınızda — eğer orijinal istek `openid` scope'u içeriyordu — yanıtta yeni bir `id_token` da döner.

**Claim'lerde hangi kullanıcı adı döner?** `name` claim'i kullanıcının Flextell hesabındaki "Ad Soyad" alanıdır. Boşsa claim de boş gelir.

**`phone_number_verified` gibi standart OIDC claim'leri destekleniyor mu?** Şu anda yalnızca `sub`, `name`, `email`, `phone_number` dönüyor. Yeni claim'ler eklendiğinde [Changelog](/resources/changelog)'da duyurulacak.

## Sonraki adımlar

<CardGroup cols={2}>
  <Card title="PKCE Akışı" icon="key" href="/authentication/pkce">
    SPA ve mobil uygulamalar için güvenli code exchange.
  </Card>

  <Card title="Token İptali" icon="power-off" href="/authentication/revoke-tokens">
    `end_session_endpoint` ile tek seferde logout.
  </Card>

  <Card title="Scopes" icon="list" href="/authentication/scopes">
    `openid`, `profile`, `email`, `phone` izinleri.
  </Card>

  <Card title="Authorization Code" icon="arrow-right" href="/authentication/authorization-code">
    OAuth akışının tüm detayları.
  </Card>
</CardGroup>
