Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

Authentifizierung verstehen: Kunden-Token nutzen, den Customer-Context im Resolver prüfen

Authentifizierung verstehen: Kunden-Token nutzen, den Customer-Context im Resolver prüfen

~8 Min. Lesezeit Zuletzt aktualisiert am 9. August 2026

Bevor Kapitel 18 die Favoriten-Mutation absichert, klärt dieses Kapitel die Grundlagen: Wie meldet sich ein Kunde bei GraphQL überhaupt an, und wie erkennt ein Resolver, wer gerade anfragt? Als praktisches, ungefährliches Beispiel dient ein neues Feld is_favorite am Event-Typ, das nur für eingeloggte Kunden sinnvoll befüllt werden kann.

Das Kunden-Token erzeugen

Magento authentifiziert GraphQL-Anfragen über dasselbe Token-System wie die REST-API: eine Mutation generateCustomerToken aus Magento_CustomerGraphQl nimmt E-Mail und Passwort entgegen und liefert ein Bearer-Token zurück.

mutation {
  generateCustomerToken(email: "kunde@example.com", password: "geheim123") {
    token
  }
}

Dieses Token wandert bei jeder folgenden Anfrage in den Authorization-Header:

Terminal
curl -s https://mironsoft.test/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{"query": "{ customer { email } }"}'

Wie der Context daraus entsteht

Magentos GraphQL-Controller liest den Authorization-Header noch vor jedem Resolver-Aufruf aus, validiert das Token und baut daraus die ContextInterface-Instanz, die jeder Resolver als zweiten Parameter erhält (Kapitel 10). Ein fehlendes oder ungültiges Token führt nicht automatisch zu einem Fehler - die Anfrage läuft einfach als Gast weiter, es sei denn, ein einzelnes Feld verlangt selbst eine Authentifizierung.

Beispiel: is_favorite-Feld mit Context-Check

app/code/Mironsoft/Event/etc/schema.graphqls
extend type Event {
    is_favorite: Boolean!
        @resolver(class: "Mironsoft\\Event\\Model\\Resolver\\IsFavorite")
        @doc(description: "Whether the current customer has favorited this event")
}
app/code/Mironsoft/Event/Model/Resolver/IsFavorite.php
<?php

declare(strict_types=1);

namespace Mironsoft\Event\Model\Resolver;

use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Mironsoft\Event\Api\Data\EventInterface;
use Mironsoft\Event\Model\ResourceModel\EventFavorite;

/**
 * Resolves the is_favorite field on the Event type. Always false for guests.
 */
class IsFavorite implements ResolverInterface
{
    /**
     * @param EventFavorite $eventFavoriteResource Resource model for the favorites linkage table
     */
    public function __construct(
        private readonly EventFavorite $eventFavoriteResource,
    ) {
    }

    /**
     * Checks whether the current customer has favorited the resolved event.
     *
     * @param Field $field Resolved GraphQL field configuration
     * @param mixed $context Resolver context, carries the customer ID/type
     * @param ResolveInfo $info GraphQL resolve tree info
     * @param array|null $value Parent Event resolver's value
     * @param array|null $args Arguments passed to this field
     * @return bool
     */
    public function resolve(
        Field $field,
        $context,
        ResolveInfo $info,
        ?array $value = null,
        ?array $args = null
    ): bool {
        /** @var EventInterface|null $event */
        $event = $value['model'] ?? null;

        if ($event === null || !$context->getExtensionAttributes()->getIsCustomer()) {
            return false;
        }

        return $this->eventFavoriteResource->isFavorite(
            (int) $context->getUserId(),
            (int) $event->getEventId()
        );
    }
}

getExtensionAttributes()->getIsCustomer() ist der zuverlässigste Weg, echte Kunden von Gästen zu unterscheiden - zuverlässiger als eine reine getUserId() > 0-Prüfung, weil getIsCustomer() vom GraphQL-Framework selbst konsistent auf Basis des validierten Tokens gesetzt wird. Für Gäste liefert das Feld einfach false zurück, statt einen Fehler zu werfen - is_favorite ist schließlich auch für Gäste ein fachlich sinnvoller, wahrer Wert ("nein, nicht favorisiert").

Die USER_TYPE_*-Konstanten im Überblick

  • UserContextInterface::USER_TYPE_GUEST - keine Authentifizierung, kein Token oder abgelaufenes/ungültiges Token.
  • UserContextInterface::USER_TYPE_CUSTOMER - gültiges Kunden-Token, das ist der für addEventToFavorites relevante Fall.
  • UserContextInterface::USER_TYPE_ADMIN - ein Admin-Token statt eines Kunden-Tokens, relevant für Kapitel 23 (ACL).
  • UserContextInterface::USER_TYPE_INTEGRATION - eine Integration (vergleichbar mit einem REST-Access-Token einer Drittanbieter-Anwendung).

Tipp: Für schnelle, wiederholte Tests während der Entwicklung lohnt sich, das Token einmal zu generieren und als Umgebungsvariable oder in der Collection des GraphQL-Clients zu speichern - Kunden-Tokens sind standardmäßig eine gewisse Zeit gültig, ein Neu-Login für jeden einzelnen Testaufruf ist nicht nötig.

Mit dem Verständnis, wie Token, Context und getIsCustomer() zusammenspielen, rüstet Kapitel 18 die Favoriten-Mutation aus Kapitel 16 mit genau diesem Wissen zu einer wirklich geschützten Mutation aus.