Ditt inloggningsflöde “fungerar” tills det inte gör det. En token går ut vid fel tillfälle, uppdatering misslyckas utan att märkas, användare blir utloggade och du hamnar i felsökning av autentisering i stället för att bygga din produkt. Så blir små buggar till stora supporttrådar.
Den här Postman Airtable JWT-automationen är för utvecklaren som vill få ut en MVP, byrån som bygger interna verktyg åt kunder, och den produktdrivna grundaren som ärligt talat är trött på att tejpa ihop autentisering. Du får en produktionsredo uppsättning endpoints för registrering, inloggning, verifiering och uppdatering, utan att behöva sätta upp en hel autentiseringstjänst.
Du får se hur workflowet hanterar säker lösenordshashning, skapande av JWT, lagring av refresh token och förutsägbara felrespons. Sedan vet du exakt vad du behöver för att köra det och hur du anpassar det till din app.
Så fungerar den här automationen
Hela n8n-workflowet, från trigger till slutligt resultat:
n8n Workflow Template: Postman + Airtable: JWT-inloggning som bara fungerar
flowchart LR
subgraph sg0["Flow 1"]
direction LR
n2@{ icon: "mdi:swap-vertical", form: "rounded", label: "Parse Login Webhook", pos: "b", h: 48 }
n3@{ icon: "mdi:cog", form: "rounded", label: "Fetch User Record", pos: "b", h: 48 }
n4["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Derive Salt and Hash"]
n5@{ icon: "mdi:cog", form: "rounded", label: "Hash Input Secret", pos: "b", h: 48 }
n6@{ icon: "mdi:cog", form: "rounded", label: "Sign Access JWT", pos: "b", h: 48 }
n7@{ icon: "mdi:cog", form: "rounded", label: "Sign Refresh JWT", pos: "b", h: 48 }
n8["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Assemble JWT Tokens"]
n9["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/merge.svg' width='40' height='40' /></div><br/>Combine JWT Outputs"]
n10@{ icon: "mdi:cog", form: "rounded", label: "Hash Refresh Token Save", pos: "b", h: 48 }
n21@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Check User Exists", pos: "b", h: 48 }
n22["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>User Missing Reply"]
n23["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Prepare Token Record"]
n24@{ icon: "mdi:cog", form: "rounded", label: "Update User Refresh Field", pos: "b", h: 48 }
n25@{ icon: "mdi:cog", form: "rounded", label: "Upsert Refresh Token", pos: "b", h: 48 }
n26["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/merge.svg' width='40' height='40' /></div><br/>Select Merge Output"]
n41["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Login Success Reply"]
n42["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Invalid Login Reply"]
n44["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Validate Login Input"]
n45["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Confirm Password Hash"]
n46["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Create JWT Payloads"]
n56["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Login Webhook Trigger"]
n57["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Bad Request Reply"]
n60@{ icon: "mdi:swap-vertical", form: "rounded", label: "Set Auth Secrets", pos: "b", h: 48 }
n26 --> n41
n3 --> n21
n44 --> n3
n44 --> n57
n56 --> n2
n21 --> n4
n21 --> n22
n45 --> n46
n45 --> n42
n9 --> n8
n8 --> n10
n6 --> n9
n23 --> n24
n23 --> n25
n46 --> n6
n46 --> n7
n7 --> n9
n4 --> n5
n5 --> n45
n25 --> n26
n2 --> n60
n24 --> n26
n60 --> n44
n10 --> n23
end
subgraph sg1["Flow 2"]
direction LR
n0@{ icon: "mdi:cog", form: "rounded", label: "Create Random Salt", pos: "b", h: 48 }
n1@{ icon: "mdi:cog", form: "rounded", label: "Hash User Password", pos: "b", h: 48 }
n14@{ icon: "mdi:cog", form: "rounded", label: "Insert User Record", pos: "b", h: 48 }
n15["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Incoming Registration Hook"]
n16["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Combine Password Salt"]
n17["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Map User Payload"]
n18["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Registration Error Reply"]
n19["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Validate Signup Request"]
n20["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Registration Success Reply"]
n40@{ icon: "mdi:swap-vertical", form: "rounded", label: "Parse Signup Request", pos: "b", h: 48 }
n49@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Check Username Free", pos: "b", h: 48 }
n50@{ icon: "mdi:cog", form: "rounded", label: "Fetch User by Username", pos: "b", h: 48 }
n51["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Username Taken Reply"]
n52["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Invalid Signup Reply"]
n53@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Check Email Free", pos: "b", h: 48 }
n54@{ icon: "mdi:cog", form: "rounded", label: "Fetch User by Email", pos: "b", h: 48 }
n55["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Email Taken Reply"]
n14 --> n20
n14 --> n18
n0 --> n16
n1 --> n17
n17 --> n14
n54 --> n53
n50 --> n49
n15 --> n40
n53 --> n0
n53 --> n55
n16 --> n1
n40 --> n19
n49 --> n54
n49 --> n51
n19 --> n50
n19 --> n52
end
subgraph sg2["Flow 3"]
direction LR
n29["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Refresh Token Webhook"]
n30["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Decode Refresh JWT"]
n31@{ icon: "mdi:cog", form: "rounded", label: "Validate Refresh Signature", pos: "b", h: 48 }
n32["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Compare Refresh Sign"]
n33@{ icon: "mdi:cog", form: "rounded", label: "Hash Refresh Lookup", pos: "b", h: 48 }
n34@{ icon: "mdi:cog", form: "rounded", label: "Check Refresh Exists", pos: "b", h: 48 }
n35@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Refresh Token Valid Check", pos: "b", h: 48 }
n36["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Build Access Payload"]
n37["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Assemble Access JWT"]
n38["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Respond New Access Token"]
n39["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Session Expired Reply"]
n47@{ icon: "mdi:swap-vertical", form: "rounded", label: "Parse Refresh Hook", pos: "b", h: 48 }
n48@{ icon: "mdi:cog", form: "rounded", label: "Sign New Access JWT", pos: "b", h: 48 }
n61@{ icon: "mdi:swap-vertical", form: "rounded", label: "Set Refresh Secrets", pos: "b", h: 48 }
n31 --> n32
n30 --> n31
n29 --> n47
n47 --> n61
n48 --> n37
n37 --> n38
n34 --> n35
n35 --> n36
n35 --> n39
n36 --> n48
n61 --> n30
n32 --> n33
n33 --> n34
end
subgraph sg3["Subflow Execution Flow"]
direction LR
n11["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Decode Access JWT"]
n12@{ icon: "mdi:cog", form: "rounded", label: "Validate HMAC Signature", pos: "b", h: 48 }
n13["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Compare Token Signatures"]
n27["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Access Token Webhook"]
n28@{ icon: "mdi:play-circle", form: "rounded", label: "Subflow Execution Trigger", pos: "b", h: 48 }
n43@{ icon: "mdi:swap-vertical", form: "rounded", label: "Parse Verify Token Hook", pos: "b", h: 48 }
n58["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Access Token Valid Reply"]
n59["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Access Token Invalid Reply"]
n62@{ icon: "mdi:swap-vertical", form: "rounded", label: "Set Verify Secrets", pos: "b", h: 48 }
n11 --> n62
n13 --> n58
n13 --> n59
n27 --> n43
n12 --> n13
n43 --> n11
n62 --> n12
n28 --> n11
end
%% Styling
classDef trigger fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
classDef ai fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
classDef aiModel fill:#e8eaf6,stroke:#3f51b5,stroke-width:2px
classDef decision fill:#fff8e1,stroke:#f9a825,stroke-width:2px
classDef database fill:#fce4ec,stroke:#c2185b,stroke-width:2px
classDef api fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef code fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
classDef disabled stroke-dasharray: 5 5,opacity: 0.5
class n28 trigger
class n21,n49,n53,n35 decision
class n22,n41,n42,n56,n57,n15,n18,n20,n51,n52,n55,n29,n38,n39,n27,n58,n59 api
class n4,n8,n23,n44,n45,n46,n16,n17,n19,n30,n32,n36,n37,n11,n13 code
classDef customIcon fill:none,stroke:none
class n4,n8,n9,n22,n23,n26,n41,n42,n44,n45,n46,n56,n57,n15,n16,n17,n18,n19,n20,n51,n52,n55,n29,n30,n32,n36,n37,n38,n39,n11,n13,n27,n58,n59 customIcon
Problemet: autentiseringens “edge cases” blir ditt heltidsjobb
Autentisering verkar enkel ända tills du släpper den. Lösenord kräver korrekt hashning och salt, tokens behöver livslängder, uppdatering kräver säker lagring och felmeddelanden måste undvika att läcka detaljer. Samtidigt försöker du bygga funktioner som användare faktiskt betalar för. Resultatet blir ofta ett halvt byggt autentiseringslager som fungerar i happy-path-testning men faller sönder i verklig användning: flera enheter, utgångna sessioner och retries. Det är inte komplexiteten i en enskild bugg. Det är hopningen.
Friktionen växer snabbt. Här brukar team fastna.
- Du slutar med att underhålla egna inloggnings-endpoints som beter sig olika i webb, mobil och interna verktyg.
- Refresh tokens lagras i klartext (eller lagras inte alls), vilket gör “logga ut överallt” omöjligt.
- Tokenverifiering blir inkonsekvent, så skyddade routes fallerar på sätt som är svåra att återskapa.
- Du lägger cirka 2 timmar i veckan på felsökning av autentisering och omtestning efter “små ändringar”.
Lösningen: en komplett JWT-auth-backend i n8n
Det här workflowet gör n8n till en fullständig autentiseringsbackend med fyra strukturerade endpoints: register, login, verify-token och refresh. En användare registrerar sig via en webhook, workflowet validerar indata, kontrollerar om e-post eller användarnamn redan är upptaget och hash:ar sedan lösenordet med SHA-512 och ett unikt salt innan användaren sparas. Vid inloggning hämtar det användarposten, räknar om hash:en för det angivna lösenordet och genererar först därefter två JWT: en kortlivad access token (cirka 15 minuter) och en långlivad refresh token (cirka 7 dagar). För uppdatering validerar workflowet refresh-JWT-signaturen, hash:ar refresh token innan uppslag, bekräftar att den inte har gått ut och utfärdar en ny access token utan att tvinga fram ny inloggning.
Workflowet startar med webhooks som din app kan anropa från valfri frontend. I mitten hanterar krypto- och kodenoder hashning, signering och validering. Till sist returneras svar direkt via “Respond to Webhook”, så Postman-tester och riktiga klienter alltid får konsekvent JSON.
Vad du får: automation vs. resultat
| Vad det här workflowet automatiserar | Resultat du får |
|---|---|
|
|
Exempel: så här ser det ut
Säg att du bygger en liten SaaS och behöver fyra endpoints: register, login, verify, refresh. Manuellt är det oftast en dags jobb med att koppla routes, hashning, tokensignering, lagring för refresh, plus en dag till med “varför fallerar det här på mobilen”. Med det här workflowet konfigurerar du secrets och Data Tables en gång, och testar sedan alla fyra anrop i Postman på cirka 30 minuter. Tokens utfärdas och verifieras på samma sätt varje gång, vilket sparar dig ett par timmar omtestning vid varje release.
Det här behöver du
- n8n-instans (testa n8n Cloud gratis)
- Alternativ för self-hosting om du föredrar det (Hostinger fungerar bra)
- Postman för att testa auth-endpoints
- n8n Data Tables för att lagra användare och refresh tokens
- Access- + refresh-secrets (generera med Node crypto-kommando)
Kompetensnivå: Medel. Du klistrar in webhook-URL:er i Postman, sätter secrets säkert och mappar ett par request/response-fält.
Vill du inte sätta upp detta själv? Prata med en automationsexpert (gratis 15-minuters konsultation).
Så fungerar det
Ett webhook-anrop träffar en av dina auth-endpoints. n8n exponerar separata webhooks för registrering, inloggning, verify-token och refresh, så din frontend kan anropa dem som ett vanligt REST API.
Indata valideras och normaliseras. Workflowet tolkar inkommande JSON, kontrollerar obligatoriska fält och svarar med ett säkert svar i stil med “bad request” när något saknas (utan att dela för mycket).
Krypto- och tokenlogik körs i mitten. Lösenord saltas och hash:as, JWT-payloads byggs och signaturer valideras med dina konfigurerade secrets. Refresh tokens hash:as innan de lagras eller slås upp, vilket innebär att en läckt tabell fortfarande är betydligt mindre användbar.
Data Tables lagrar källan till sanningen. Användarposter hamnar i en users-tabell, refresh tokens hamnar i en refresh_tokens-tabell med en utgångstidsstämpel, och workflowet returnerar tokens (eller fel) via “Respond to Webhook”.
Du kan enkelt justera token-livslängder för att matcha din risknivå utifrån dina behov. Se den fullständiga implementationsguiden nedan för alternativ för anpassning.
Steg-för-steg-guide för implementering
Steg 1: konfigurera webhook-triggers
Sätt upp de tre publika ingångarna för registrering, inloggning och tokenverifiering så att externa klienter kan anropa workflowet.
- Öppna Incoming Registration Hook och ställ in Path till
register-useroch HTTP Method tillPOST. - Öppna Login Webhook Trigger och ställ in Path till
loginoch HTTP Method tillPOST. - Öppna Access Token Webhook och ställ in Path till
verify-tokenoch HTTP Method tillPOST. - Öppna Refresh Token Webhook och ställ in Path till
refreshoch HTTP Method tillPOST. - Säkerställ att varje webhook använder Response Mode inställt på
responseNodeså att svaren returneras av svarsnoderna.
Steg 2: koppla datalagring för användar- och tokentabeller
Detta workflow lagrar användare och refresh tokens i Data Tables. Konfigurera tabell-ID:n och lägg till autentiseringsuppgifter för alla Data Table-noder.
- I Fetch User by Username, ställ in Data Table till er användartabell och behåll Operation som
getmed Limit1. - I Fetch User by Email och Fetch User Record, välj samma användartabell och säkerställ att filtren använder
{{$json.email}}. - I Insert User Record, välj användartabellen och mappa kolumner till
{{$json.email}},{{$json.username}}och{{$json.password_hash}}. - I Update User Refresh Field, ställ in användartabellen och uppdatera refresh_token med
{{$json.refreshToken}}. - I Upsert Refresh Token och Check Refresh Exists, välj er refresh token-tabell och bekräfta filter för
{{$json.token_hash}}och{{$json.userId}}. - Autentiseringsuppgifter krävs: Koppla era Data Table-autentiseringsuppgifter till alla dataTable-noder (Fetch User by Username, Fetch User by Email, Fetch User Record, Insert User Record, Update User Refresh Field, Upsert Refresh Token, Check Refresh Exists).
[YOUR_ID]. Ersätt varje Data Table-ID med era faktiska tabell-ID:n, annars kommer läsningar/skrivningar att misslyckas.Steg 3: konfigurera tolkning och validering för registrering
Dessa noder tolkar registreringspayloaden och genomför grundläggande validering innan användaren skapas.
- I Parse Signup Request, verifiera att fältmappningar för email, username och password är satta till
{{$json.body.email}},{{$json.body.username}}och{{$json.body.password}}. - Granska Validate Signup Request för att säkerställa att den kräver
password.length >= 8och konverterar e-postadresser till gemener som förväntat. - Bekräfta routingen: Parse Signup Request → Validate Signup Request → Fetch User by Username → Check Username Free.
- Säkerställ att avvisningsvägar svarar med Invalid Signup Reply och Username Taken Reply.
Steg 4: bygg hashing-pipelinen för registrering
Denna sekvens skapar ett salt, hash:ar lösenordet och skriver den nya användarposten.
- Från Check Email Free, bekräfta att true-grenen går till Create Random Salt och false-grenen till Email Taken Reply.
- I Create Random Salt, behåll Action inställt på
generate, Encoding Type påhexoch Data Property Name påsalt. - Säkerställ att Combine Password Salt använder den inbyggda koden för att sätta
passwordWithSaltoch att Hash User Password sedan hash:ar{{$json.passwordWithSalt}}med TypeSHA512. - Verifiera att Map User Payload output:ar
password_hashi formatetsalt:hash. - Koppla Map User Payload → Insert User Record → Registration Success Reply, och låt Registration Error Reply ligga på felvägen.
SHA512) genom hela registrering och inloggning för att undvika avvikelser i Confirm Password Hash.Steg 5: konfigurera tolkning av inloggning och verifiering av användare
Inloggningsflödet tolkar inloggningsuppgifter, validerar indata, hämtar användaren och jämför lösenordshashen.
- I Parse Login Webhook, behåll mappningar till
{{$json.body.email}}och{{$json.body.password}}. - I Set Auth Secrets, ställ in ACCESS_SECRET och REFRESH_SECRET till era signeringsnycklar (lämna dem inte tomma).
- Bekräfta att Validate Login Input routar success till Fetch User Record och failure till Bad Request Reply.
- Säkerställ att Check User Exists routar success till Derive Salt and Hash och failure till User Missing Reply.
- Verifiera Derive Salt and Hash → Hash Input Secret (med
{{$json.passwordWithSalt}}) → Confirm Password Hash.
Steg 6: generera och lagra JWT-tokens
Efter bekräftat lösenord skapas och lagras tokens. Denna del innehåller en parallell gren.
- Låt Create JWT Payloads vara som den är så att den bygger
accessSignatureInputochrefreshSignatureInput. - Create JWT Payloads output:ar till både Sign Access JWT och Sign Refresh JWT parallellt.
- Verifiera att Sign Access JWT använder
{{$json.accessSignatureInput}}och{{$('Set Auth Secrets').item.json.ACCESS_SECRET}}. - Verifiera att Sign Refresh JWT använder
{{$json.refreshSignatureInput}}och{{$('Set Auth Secrets').item.json.REFRESH_SECRET}}. - Säkerställ att Combine JWT Outputs slår ihop med Fields to Match inställt på
userIdoch skickar vidare till Assemble JWT Tokens. - Bekräfta Assemble JWT Tokens → Hash Refresh Token Save → Prepare Token Record.
- Prepare Token Record output:ar till både Update User Refresh Field och Upsert Refresh Token parallellt.
- Behåll merge-grenväljaren: Update User Refresh Field och Upsert Refresh Token → Select Merge Output → Login Success Reply.
Steg 7: konfigurera flöde för verifiering av access token
Denna route validerar access tokens och returnerar lyckat eller misslyckat resultat.
- Verifiera att Parse Verify Token Hook mappar access_token till
{{$json.body.access_token}}. - I Set Verify Secrets, ställ in ACCESS_SECRET och REFRESH_SECRET så att de matchar secrets i inloggningsflödet.
- Säkerställ Decode Access JWT → Set Verify Secrets → Validate HMAC Signature → Compare Token Signatures.
- Bekräfta att success routas till Access Token Valid Reply och failure till Access Token Invalid Reply.
Steg 8: konfigurera flöde för rotation av refresh token
Detta flöde validerar refresh tokens och utfärdar en ny access token.
- I Parse Refresh Hook, mappa refresh_token till
{{$json.body.refresh_token}}. - Sätt secrets i Set Refresh Secrets så att de matchar inloggningsflödet.
- Bekräfta vägen: Decode Refresh JWT → Validate Refresh Signature → Compare Refresh Sign → Hash Refresh Lookup → Check Refresh Exists → Refresh Token Valid Check.
- Säkerställ att Refresh Token Valid Check routar success till Build Access Payload och failure till Session Expired Reply.
- Verifiera Build Access Payload → Sign New Access JWT (med
{{$('Set Refresh Secrets').item.json.ACCESS_SECRET}}) → Assemble Access JWT → Respond New Access Token.
Steg 9: lägg till svar för felhantering
Flera noder är konfigurerade att fortsätta vid fel och returnera tydliga svar för ogiltiga förfrågningar.
- Behåll noderna för felsvar kopplade: Bad Request Reply, Invalid Login Reply, User Missing Reply, Email Taken Reply, Username Taken Reply, Invalid Signup Reply, Session Expired Reply och Registration Error Reply.
- Bekräfta att routing vid fel i Validate Signup Request, Validate Login Input, Confirm Password Hash, Compare Token Signatures och Insert User Record fortsatt är aktiverad (Continue On Fail).
Steg 10: testa och aktivera ert workflow
Kör varje webhook-sökväg med exempelpayloads för att verifiera hela autentiseringslivscykeln.
- Klicka på Test Workflow och skicka en POST till
/register-usermed{"email":"[email protected]","username":"testuser","password":"password123"}. - Skicka en POST till
/loginmed samma inloggningsuppgifter och bekräfta att Login Success Reply returneraraccessTokenochrefreshToken. - Skicka en POST till
/verify-tokenmed{"access_token":"och bekräfta att Access Token Valid Reply returnerar lyckat resultat."} - Skicka en POST till
/refreshmed{"refresh_token":"och bekräfta att Respond New Access Token returnerar en ny access token."} - När testerna lyckas, växla workflowet till Active för användning i produktion.
Vanliga fallgropar
- Behörigheter för n8n Data Tables kan ställa till det. Om inserts eller uppslag misslyckas, kontrollera vald tabell i varje Data Table-nod och bekräfta att funktionen är aktiverad i din workspace.
- Om du använder Wait-noder eller extern rendering varierar processtiderna. Öka väntetiden om noder längre fram misslyckas på grund av tomma svar.
- Standardprompter i AI-noder är generiska. Lägg in er tonalitet tidigt, annars kommer du att redigera output för alltid.
Vanliga frågor
Cirka 45 minuter om dina Data Tables är klara.
Nej. Du konfigurerar främst credentials, secrets och request bodies i Postman. Du kan fortfarande anpassa kodenoder senare om du vill ha mer kontroll.
Ja. n8n har ett gratis self-hosted-alternativ och en gratis provperiod på n8n Cloud. Cloud-planer börjar på 20 USD/månad för högre volymer. Du behöver också räkna in infrastrukturkostnader (en liten VPS räcker ofta).
Två alternativ: n8n Cloud (hanterat, enklast att komma igång) eller self-hosting på en VPS. För self-hosting är Hostinger VPS prisvärt och hanterar n8n bra. Self-hosting ger dig obegränsat antal körningar men kräver grundläggande serverhantering.
Ja, men planera noggrant. Du kan bygga ut refresh-flödet genom att uppdatera valideringen av refresh token och skrivstegen i Data Table (”Upsert Refresh Token” och relaterad hash-/uppslagslogik) så att varje uppdatering utfärdar en ny refresh token och ogiltigförklarar den gamla. Vanliga anpassningar är att ändra token-livslängder, lägga till användarroller i JWT-payloaden och kräva starkare lösenordsregler i valideringen vid registrering.
Oftast är det fel tabell som valts i en Data Table-nod, eller så är Data Tables-funktionen inte aktiverad i den n8n-workspace:en. Dubbelkolla tabellmappningarna för “users” och “refresh_tokens”, och kör sedan ett enskilt webhook-test från Postman igen. Om det fortfarande misslyckas, rotera credential och bekräfta att din n8n-instans kan persistera data (vissa flyktiga deploymenter återställs).
I de flesta uppsättningar klarar den gott och väl en MVP: hundratals inloggningar per dag är typiskt. Om du self-hostar är den främsta begränsningen din server och hur snabbt dina Data Tables svarar.
För auth-flöden: ja, i de flesta fall. Du behöver kryptooperationer, grenlogik och konsekventa webhook-svar, och n8n är helt enkelt byggt för den typen av “backend-liknande” workflow. Zapier och Make kan kännas enklare i början, men de blir klumpiga för säker tokenhantering och du kommer att slå i begränsningar när du lägger till verifiering och refresh. Self-hosting är också viktigt om du vill ha förutsägbara kostnader. Om du är osäker: prata med en automationsexpert och rimlighetskontrollera upplägget innan du släpper det.
Autentisering är den typen av sak du vill sätta upp en gång och sluta tänka på. Det här workflowet tar dig dit, med färre överraskningar när riktiga användare dyker upp.
Kontakta oss
Hör av dig, så diskuterar vi hur just din verksamhet kan dra nytta av alla fantastiska möjligheter som AI skapar.