Ein generiertes Token abrufen

Describe the problem/error/question

What is the error message (if any)? Not an error. This is a “how do I” question.

I know I’m doing this insecurely. This question is trying to rectify that. I have this workflow to generate a bearer token if the expiration time has lapsed. I want to use stored username/password, and if possible, store the bearer token until it needs to be replaced.

The workflow gets the username and password, along with the current bearer token, it’s expiration from a local store.

If the bearer token is expired, it uses an http node to call the server to have it generate a new token.

Finally, it returns the valid token to the calling workflow. I use this for multiple clients, so I would like to be able to specify which credentials it will be using when I call this workflow.

The purpose of this post is to secure the credentials. Since I use this for many clients, any solution should be able to call the appropriate credentials.

Please share your workflow

Share the output returned by the last node

This is the bearer token (expired!) returned by the API server.


[
  {
    "mosyle": 
    {
      "AuthToken": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE3Nzg3ODMxMDEsImV4cCI6MTc3ODg2OTUwMSwiaXNzIjoiTW9zeWxlIiwiZGF0YSI6eyJWWE5sY2tsRSI6Ik5qVTNOak15TWc9PSIsIlpXMWhhV3c9IjoiYmpodVFHcDFjM1JwWTJWaGJtUnFiM2x1WVhSc0xtOXladz09IiwiWVdOalpYTnpWRzlyWlc0PSI6Ik5USXlOV0V6TnpZeVlUWmhNamRqTldabFpEVmhOVEl6TjJRek4yTTNOemMzTjJZM04yUXpNMlExWmpRM05UUTFZVGMyWldVMFpqVmpOemMxTW1FM013PT0ifX0.WtiAgibdCQ2pp03Za-FJ2BlGRYy0wxd3vhxIiY-6mDE"
    }
  }
]

Information on your n8n setup

  • n8n version: 2.20.6
  • Database (default: SQLite): PostgresQL 15
  • n8n EXECUTIONS_PROCESS setting (default: own, main): Own
  • Running n8n via (Docker, npm, n8n cloud, desktop app): Docker on Digital Ocean.
  • Operating system: Ubuntu 24.04

@russellkg Hallo! Wenn du das auf deinem Server machst, z. B. das Token erstellst, oder wenn du Kontrolle über den HTTPS-Server hast, der zum Generieren des Tokens verwendet wird, könntest du einen Autorisierungscode erstellen, den die Anfrage haben muss, um auf das Token zuzugreifen.

Was genau lässt dich denken, dass es unsicher ist, und wo möchtest du Verbesserungen?

willkommen in der n8n-gemeinschaft @russellkg

ich würde auch schützen, wo die geheimnisse gespeichert werden. das ideal ist, benutzernamen/passwörter in den credentials von n8n oder in einem secrets manager zu speichern, nicht in data tables oder ausführungsausgaben. für mehrere kunden kann der workflow eine kundenkennung empfangen und basierend darauf die richtige anmeldedaten verwenden, um das token zu generieren oder zu erneuern.

Ich übergebe an verschiedenen Stellen ein Client-‘Flag’. Ich habe einen Teil davon bereits implementiert.

Der Hauptgrund, warum ich es zunächst so gemacht habe, war, dass ich schnell etwas zum Laufen bringen musste. Jetzt ist es an der Zeit, zurückzugehen und meine Produktivitätsabkürzung zu beheben.

Wie ich in meinem ursprünglichen Beitrag sagte, ist das Bearer-Token, das in diese Nachricht kopiert wurde, ein Beispiel. Es ist abgelaufen, und selbst wenn es nicht abgelaufen wäre, müssten Sie herausfinden, welcher Client, welcher Mandant und welche Anmeldedaten mit diesem Bearer-Token erforderlich sind. In jedem Fall gibt es an diesem Punkt einen fehlgeschlagenen Authentifizierungsfehler zurück. Es ist nicht möglich, dieses Token zu authentifizieren oder zu erneuern. Hinzu kommt, dass diese Übung speziell dazu dient, das aus meinen Workflows herauszunehmen.

Das bringt mich zum nächsten Problem.

Sobald der Server mir ein Bearer-Token zurückgibt, wo speichere ich es für die 24 Stunden, in denen es gültig ist? Ich glaube nicht, dass der Bearer-Token-Knoten von einem Workflow aus bearbeitet werden kann.

Ein Teil des Grundes, warum ich es auf diese Weise gemacht habe, war, dass ich nicht jedes Mal ein Bearer-Token generieren wollte, wenn ich mich verbinde, und es ist nicht offensichtlich, was ich mit dem Bearer machen soll.

Ich weiß, dass ich noch mehr Fragen haben werde.

Voraus vielen Dank.

-Russ

@russellkg
Ich würde den Token nicht in eine n8n-Bearer-Token-Anmeldedaten zurückschreiben. Diese Anmeldedaten eignen sich besser für stabile Secrets, nicht für deinen Fall.
In diesem Fall würde ich den Token in einer Cache-/Tabellenebene mit clientKey, accessToken und expiresAt speichern, etwa in Redis, und einen wiederverwendbaren Workflow “Get Valid Token” erstellen. Dieser Workflow würde prüfen, ob für diesen Client bereits ein gültiger Token vorhanden ist; wenn ja, gibt er den Token zurück; wenn er abgelaufen ist, generiert er einen neuen, aktualisiert den Cache und gibt den neuen Wert zurück.

Vielleicht hilft das bei einem Teil davon.

Token-Caching über eine Datei ist in Ordnung – eine JSON-Datei pro Client, benannt mit dem Client-Schlüssel, ist ein sauberes Muster und skaliert gut.

Das eigentliche Problem ist, dass Anmeldedaten (E-Mail, Passwort, accessToken) im Workflow selbst leben – Daten von angehefteten Knoten zeigen sich in der Ausführungshistorie und jeder mit Workflow-Zugriff kann sie als Klartext in der Workflow-JSON sehen.

**Die Lösung, die ich verwende, sind UMGEBUNGSVARIABLEN. Lade eine .env-Datei beim n8n-Start, damit die Anmeldedaten nie im Workflow sind. Ich habe aufgeschrieben, wie ich das mache:

Mein anderer Beitrag:

Kurze Version – lade eine .env-Datei über ein Bat-/Shell-Skript beim Start, setze N8N_BLOCK_ENV_ACCESS_IN_NODE=false, dann verweise per Ausdruck, Variable Anchor wie {{ $env.MOSYLE_EMAIL_CR }} usw. Die UI wirft eine Warnung aus, die besagt „nicht zugänglich", aber zur Laufzeit löst es sich perfekt auf. Pro Client einfach mit Namespace: MOSYLE_EMAIL_CLIENT1, MOSYLE_EMAIL_CLIENT2 und so weiter.

Der HTTP Request-Knoten verwendet manuelle Header-/Body-Parameter um E-Mail, Passwort, accessToken zu übergeben – jedes Feld, das Ausdrücke akzeptiert, also funktionieren Umgebungsvariablen perfekt dort

Eine Sache allerdings – Umgebungsvariablen werden nur beim Start geladen, also versuche nicht, den Bearer Token selbst dort zu speichern. Diesen Teil hast du eigentlich schon mit dem Datei-Schreiben gelöst. Die Aufteilung ist: statische Anmeldedaten (E-Mail/Passwort/accessToken) gehen in .env, dynamischer Bearer Token bleibt in der JSON-Datei. Nichts Sensibles im Workflow, und deine vorhandene Token-Aktualisierungslogik funktioniert genau wie zuvor.

Tatsächlich ist die Überprüfung des Ablaufdatums aus dem Ablauffeld des Tokens nicht sehr zuverlässig (das Token kann aus einem anderen Grund widerrufen werden).

Ein besserer Ansatz ist:

  • Erstelle für jeden Token, den du verwenden möchtest, ein neues Credential vom Typ Bearer (oder Credentials vom Typ Header, wenn das Feld einen benutzerdefinierten Namen hat).
  • Füge einen separaten Workflow hinzu, um regelmäßig zu überprüfen, ob das Token noch aktiv ist (z. B. einen bestimmten Endpunkt abfragen/grundlegende Daten abrufen – nur um sicherzustellen, dass es aktiv ist) für jedes Credential. Oder füge einen Sub-Workflow mit dieser Prüflogik hinzu, der als Proxy-Methode funktioniert, die HTTP-Methode, URL, Query, Body, Credential-Name/Token-Namen und den zu verwendenden Namen akzeptiert und diesen Sub-WF von jedem übergeordneten Element aus aufruft, das ein Token verwenden sollte
  • Wenn das Token nicht aktiv ist (abgelaufen/ungültig oder aus anderen Gründen) >> rufe einen /login-Endpunkt auf, um ein neues Token zu holen, und aktualisiere das Credential über den HTTP Node und die n8n REST API patch /credentials/{id}

Die Methode funktioniert gut, wenn du nicht viele Tokens hast; ansonsten kann der Datei-Ansatz besser sein.

Und deaktiviere die Ausführungshistorie für den Workflow, der ein Token generiert. So:

Ok. After much research and some AI added in, I’ve implemented a workflow. To highlight the parameters:

  • I have several clients using different tenants on the Mosyle platform.
  • n8n doesn’t (yet?) have a way to call credentials via an expression
  • Multiple workflows that do the same thing with different credentials is a recipe for nightmares

I’m using UpStash to store the credentials securely.

Here’s the workflow:

I think this is decent. It uses what @tamy.santos suggests. It doesn’t implement periodically checking the tokent as @barn4k suggested. That simply hasn’t been an issue. I’ll keep it under my hat in case it becomes and issue.

I also sanitized my workflows to verify I don’t have credentials laying around, waiting for anyone to happen along.