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

# Vergelijking van authenticatiemethodes - Laravel Bluesky

> Uitleg over de verschillen tussen App Password (LegacyAgent) en OAuth (OAuthAgent) in Laravel Bluesky, de interne architectuur en codevoorbeelden.

## Overzicht

Laravel Bluesky ondersteunt twee authenticatiemethodes. Na authenticatie zijn de API-aanroepen voor beide methodes identiek.

| Onderwerp                     | App Password                                      | OAuth                                            |
| ----------------------------- | ------------------------------------------------- | ------------------------------------------------ |
| Interne klassen               | `LegacyAgent` / `LegacySession`                   | `OAuthAgent` / `OAuthSession`                    |
| Entrypoint                    | `Bluesky::login()`                                | `Bluesky::withToken(OAuthSession)`               |
| Private key                   | Niet nodig                                        | `BLUESKY_OAUTH_PRIVATE_KEY` vereist              |
| Autorisatie door de gebruiker | Niet nodig                                        | Vereist (goedkeuring in de browser)              |
| Uitvoering op de achtergrond  | ✅ Uitstekend geschikt                             | ✅ Mogelijk (refresh\_token opslaan)              |
| Sessiesleutels                | `accessJwt` / `refreshJwt`                        | `access_token` / `refresh_token`                 |
| Deprecatie gepland            | **Nee**                                           | —                                                |
| Belangrijkste toepassing      | Automatisch posten, notificaties, batchverwerking | Handelen namens gebruikers, Socialite-integratie |

<Info>
  De naam `LegacyAgent` verwijst naar "de authenticatiemethode van vóór OAuth", maar App Password zelf wordt niet uitgefaseerd. Voor scenario's zonder gebruikersinteractie, zoals notificaties en automatisch posten, is App Password eenvoudiger en beter geschikt.
</Info>

## Architectuur

```mermaid theme={null}
classDiagram
    class BlueskyManager {
        +login(identifier, password) Factory
        +withToken(session) Factory
        +agent() Agent
        +check() bool
        +refreshSession() Factory
    }
    class LegacyAgent {
        +session LegacySession
        +http() PendingRequest
        +refreshSession() self
    }
    class OAuthAgent {
        +session OAuthSession
        +http() PendingRequest
        +refreshSession() self
    }
    class LegacySession {
        +accessJwt
        +refreshJwt
        +did
        +handle
        +token() string
        +refresh() string
    }
    class OAuthSession {
        +access_token
        +refresh_token
        +did
        +iss
        +token() string
        +refresh() string
        +issuer() string
    }

    BlueskyManager --> LegacyAgent : login()
    BlueskyManager --> OAuthAgent : withToken(OAuthSession)
    BlueskyManager --> LegacyAgent : withToken(LegacySession)
    LegacyAgent --> LegacySession : holds
    OAuthAgent --> OAuthSession : holds
```

`BlueskyManager` is de implementatie achter de `Bluesky` Facade. Je stelt een agent in via `login()` of `withToken()`, en de API-aanroepen daarna gebruiken bij beide authenticatiemethodes dezelfde methodes.

## App Password (LegacyAgent)

### Authenticatieflow

```mermaid theme={null}
sequenceDiagram
    participant App as Laravel-app
    participant Bluesky as Bluesky-server

    App->>Bluesky: createSession(identifier, password)
    Bluesky-->>App: LegacySession (accessJwt + refreshJwt)
    App->>App: LegacyAgent::create(session)
    App->>Bluesky: API-aanroep (Bearer accessJwt)
    Bluesky-->>App: Response
    Note over App: Als accessJwt verlopen is
    App->>Bluesky: refreshSession (refreshJwt)
    Bluesky-->>App: Nieuwe accessJwt + refreshJwt
```

### Bluesky::login()

Je hoeft alleen het App Password in `.env` in te stellen en `login()` aan te roepen.

```dotenv theme={null}
BLUESKY_IDENTIFIER=your-handle.bsky.social
BLUESKY_APP_PASSWORD=xxxx-xxxx-xxxx-xxxx
```

```php theme={null}
use Revolution\Bluesky\Facades\Bluesky;

$response = Bluesky::login(
    identifier: config('bluesky.identifier'),
    password: config('bluesky.password'),
)->post('Hello Bluesky');
```

### LegacySession hergebruiken

Elke keer `login()` aanroepen betekent elke keer een API-request. Het is efficiënter om de sessie te cachen en te hergebruiken.

```php theme={null}
use Revolution\Bluesky\Facades\Bluesky;
use Revolution\Bluesky\Session\LegacySession;

// Eerste keer inloggen en de sessie opslaan
Bluesky::login(
    identifier: config('bluesky.identifier'),
    password: config('bluesky.password'),
);
cache()->put('bluesky_session', Bluesky::agent()->session()->toArray(), now()->addDay());

// Daarna herstellen uit de cache
$session = LegacySession::create(cache('bluesky_session', []));
Bluesky::withToken($session);

// Vernieuwen als het access token verlopen is
if (! Bluesky::check()) {
    Bluesky::refreshSession();
}

$response = Bluesky::post('Hello from cached session');
```

### Belangrijkste sleutels van LegacySession

| Sleutel      | Inhoud                   | Methode     |
| ------------ | ------------------------ | ----------- |
| `accessJwt`  | Access token             | `token()`   |
| `refreshJwt` | Refresh token            | `refresh()` |
| `did`        | Bluesky DID              | `did()`     |
| `handle`     | Handle                   | `handle()`  |
| `email`      | E-mailadres              | `email()`   |
| `active`     | Of het account actief is | `active()`  |

### Geschikte use cases

* Automatisch posten via background jobs en queue-verwerking
* Notificaties via een Laravel Notification-kanaal
* Batchverwerking en scheduling
* Posten met het account van de applicatie zelf

## OAuth (OAuthAgent)

### Authenticatieflow

```mermaid theme={null}
sequenceDiagram
    participant User as Gebruiker
    participant App as Laravel-app
    participant Bluesky as Bluesky-server

    User->>App: Inlogformulier versturen (handle invoeren)
    App->>Bluesky: PAR-request (inclusief login_hint)
    Bluesky-->>App: request_uri
    App->>Bluesky: Redirect naar het autorisatie-endpoint
    User->>Bluesky: Goedkeuring via inloggen bij Bluesky
    Bluesky-->>App: Callback (code + iss)
    App->>Bluesky: Tokenuitwisseling met DPoP
    Bluesky-->>App: OAuthSession (access_token + refresh_token)
    App->>User: Inloggen voltooid
    App->>Bluesky: API-aanroep (DPoP access_token)
    Bluesky-->>App: Response
```

### Bluesky::withToken()

Je geeft de via Socialite verkregen `OAuthSession` door aan `withToken()`.

```php theme={null}
use Revolution\Bluesky\Facades\Bluesky;
use Revolution\Bluesky\Session\OAuthSession;

// Herstellen uit de Laravel-sessie (webrequest)
$session = OAuthSession::create(session('bluesky_session'));
$timeline = Bluesky::withToken($session)->getTimeline();
```

Ook in background jobs of de console kun je een `OAuthSession` samenstellen uit waarden die in de database zijn opgeslagen.

```php theme={null}
use Revolution\Bluesky\Facades\Bluesky;
use Revolution\Bluesky\Session\OAuthSession;

$session = OAuthSession::create([
    'did'           => $user->did,
    'refresh_token' => $user->refresh_token,
    // Voor accounts buiten bsky.social geef je ook iss op
    // 'iss'        => $user->iss,
]);

$response = Bluesky::withToken($session)
                   ->refreshSession()
                   ->post('Hello from OAuth');
```

### Belangrijkste sleutels van OAuthSession

| Sleutel               | Inhoud                                     | Methode         |
| --------------------- | ------------------------------------------ | --------------- |
| `access_token`        | Access token                               | `token()`       |
| `refresh_token`       | Refresh token (slechts één keer bruikbaar) | `refresh()`     |
| `did` / `sub`         | Bluesky DID                                | `did()`         |
| `iss`                 | URL van de autorisatieserver               | `issuer()`      |
| `profile.handle`      | Handle                                     | `handle()`      |
| `profile.displayName` | Weergavenaam                               | `displayName()` |

<Warning>
  Een OAuth refresh\_token is maar één keer bruikbaar. Gebruik het `OAuthSessionUpdated`-event en werk na een tokenvernieuwing altijd de database bij. Zie [Socialite](/nl/packages/laravel-bluesky/socialite) voor de details.
</Warning>

### Geschikte use cases

* Gebruikerslogin via Socialite
* API-aanroepen namens een gebruiker
* Situaties waarin je per gebruiker met een ander account moet werken

## API-aanroepen na authenticatie zijn identiek

Bij beide authenticatiemethodes gebruik je na `withToken()` dezelfde API-methodes.

```php theme={null}
use Revolution\Bluesky\Facades\Bluesky;
use Revolution\Bluesky\Session\LegacySession;
use Revolution\Bluesky\Session\OAuthSession;

// App Password
Bluesky::login(config('bluesky.identifier'), config('bluesky.password'));

// Of OAuth
$session = OAuthSession::create(session('bluesky_session'));
Bluesky::withToken($session);

// ↓ De API-aanroepen hierna zijn volledig identiek ↓

Bluesky::post('Hello Bluesky');
Bluesky::getTimeline();
Bluesky::getProfile();
Bluesky::searchPosts(q: '#laravel');
```

`BlueskyManager` gebruikt intern een `LegacyAgent` of `OAuthAgent`, maar dat heeft geen invloed op de aanroepende code.

## Welke moet je kiezen?

```mermaid theme={null}
flowchart TD
    A["Welke authenticatiemethode gebruik je?"] --> B{"Moeten gebruikers inloggen<br>met hun Bluesky-account?"}
    B -->|"Ja"| C["OAuth (OAuthAgent)<br>Socialite-integratie"]
    B -->|"Nee"| D{"Werk je met het account<br>van de app zelf?"}
    D -->|"Ja"| E["App Password (LegacyAgent)<br>eenvoudig in beheer"]
    D -->|"Namens meerdere gebruikers handelen"| C
```

| Situatie                                  | Aanbevolen   |
| ----------------------------------------- | ------------ |
| Automatisch posten, notificaties, batches | App Password |
| Gebruikersloginfunctionaliteit            | OAuth        |
| Alleen background jobs                    | App Password |
| Handelen namens gebruikers nodig          | OAuth        |
| Eenvoud in beheer voorop                  | App Password |
| Nadruk op security en rechtenbeheer       | OAuth        |

<Tip>
  Bij twijfel is indelen op doel het duidelijkst: "de app handelt zelf" betekent App Password, "de gebruiker handelt" betekent OAuth. Je kunt beide ook combineren; een veelvoorkomende opzet is App Password voor notificaties en OAuth voor gebruikerslogin.
</Tip>

## Referenties

* [Basic client](/nl/packages/laravel-bluesky/basic-client) — API-operaties na authenticatie
* [Socialite](/nl/packages/laravel-bluesky/socialite) — details van de OAuth-flow
* [Notificatiekanaal](/nl/packages/laravel-bluesky/notification) — notificaties met App Password / OAuth
* Source: [invokable/laravel-bluesky](https://github.com/invokable/laravel-bluesky)


## Related topics

- [BlueskyManager en HasShortHand](/nl/packages/laravel-bluesky/bluesky-manager.md)
- [Notificatiekanaal - Laravel Bluesky](/nl/packages/laravel-bluesky/notification.md)
- [Socialite - Laravel Bluesky](/nl/packages/laravel-bluesky/socialite.md)
- [Basic client - Laravel Bluesky](/nl/packages/laravel-bluesky/basic-client.md)
- [Uitvoeringscontrole van queue-jobs](/nl/advanced/queue-job-control.md)
