This workflow corresponds to n8n.io template #13703 — we link there as the canonical source.
This workflow follows the Form → Form Trigger recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "oYwnHDD0m2EAdXpi",
"name": "Register users and authenticate with magic links using Google Sheets",
"tags": [],
"nodes": [
{
"id": "dcaa8a9d-abdd-41a8-a359-868318d7f661",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
160,
608
],
"parameters": {
"color": 7,
"width": 1904,
"height": 384,
"content": "## 1. Login\nValidate username and password against Google Sheets, then reuse or issue a new token and redirect to the auth endpoint."
},
"typeVersion": 1
},
{
"id": "44324518-59de-4068-b49d-da5b9cabcf66",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
160,
224
],
"parameters": {
"color": 7,
"width": 1232,
"height": 288,
"content": "## 0. Register\nCollect an email address via form, generate credentials and a one-time token, save the user to Google Sheets, and send an onboarding email with the login link."
},
"typeVersion": 1
},
{
"id": "2472b7c4-cd6e-4194-8d12-59c4249ea7f3",
"name": "Append or update row in sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
688,
320
],
"parameters": {
"columns": {
"value": {
"role": "Property Manager",
"token": "YOUR_CREDENTIAL_HERE",
"password": "YOUR_CREDENTIAL_HERE",
"username": "={{ $json.email }}"
},
"schema": [
{
"id": "username",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "username",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "role",
"type": "string",
"display": true,
"required": false,
"displayName": "role",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "password",
"type": "string",
"display": true,
"required": false,
"displayName": "password",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "token",
"type": "string",
"display": true,
"required": false,
"displayName": "token",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"username"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "name",
"value": "Sheet2"
},
"documentId": {
"__rl": true,
"mode": "url",
"value": "https://docs.google.com/spreadsheets/d/YOUR_SPREADSHEET_ID"
}
},
"typeVersion": 4.7
},
{
"id": "d7f38863-74ee-4bb9-bb4d-2fd445594eea",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
160,
1072
],
"parameters": {
"color": 7,
"width": 1696,
"height": 400,
"content": "## 2. Auth\nValidate the one-time token via Google Sheets, generate a session id (sid), set an HttpOnly cookie, clear the token, and redirect to the profile page."
},
"typeVersion": 1
},
{
"id": "891d65a6-0b6c-474d-b029-d4702c8e4174",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
160,
1552
],
"parameters": {
"color": 7,
"width": 1424,
"height": 416,
"content": "## 3. Profile\nRead the sid cookie, look up the active session in Google Sheets, and render a profile page \u2014 or redirect to login if the session is invalid."
},
"typeVersion": 1
},
{
"id": "fee598fe-64d8-469e-be7d-745bd2be40e4",
"name": "Prepare sid",
"type": "n8n-nodes-base.code",
"position": [
1248,
1088
],
"parameters": {
"jsCode": "function makeSid(len = 48) {\n const alphabet = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n let out = \"\";\n // Mix time + random to reduce collisions\n let seed = Date.now().toString(36) + \"-\" + Math.random().toString(36).slice(2);\n\n out += seed.replace(/[^a-z0-9-]/gi, \"\").slice(0, 12);\n\n while (out.length < len) {\n out += alphabet[Math.floor(Math.random() * alphabet.length)];\n }\n return out.slice(0, len);\n}\n\nconst sid = makeSid(64);\n\nreturn { json: { sid } };\n"
},
"typeVersion": 2
},
{
"id": "f8747e29-893d-4e5d-916c-bb56975eb881",
"name": "Generate token",
"type": "n8n-nodes-base.code",
"position": [
1328,
816
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "function makeToken(len = 32) {\n let out = '';\n while (out.length < len) {\n out += Math.random().toString(36).slice(2); // Strip the leading \"0.\"\n }\n return out.slice(0, len);\n}\nconst token = makeToken()\nreturn {token};"
},
"typeVersion": 2
},
{
"id": "fd48786d-6e97-4361-bce0-40dc80596ba2",
"name": "If has token in DB",
"type": "n8n-nodes-base.if",
"position": [
976,
640
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "df0d0deb-4db8-4ef7-9bd0-c79ab6fb4f35",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $('Check username/password').item.json.token }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "43b3e0a0-c749-4b08-8cc1-0e84fe357bed",
"name": "If has token",
"type": "n8n-nodes-base.if",
"position": [
464,
1200
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "51cff10a-dac2-4480-a177-3b6166e4fbdf",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $('Auth').item.json.query.token }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "18b1b20d-06cb-44c5-b295-2966ff15c84f",
"name": "Search by token",
"type": "n8n-nodes-base.googleSheets",
"position": [
736,
1184
],
"parameters": {
"options": {},
"filtersUI": {
"values": [
{
"lookupValue": "={{ $('Auth').item.json.query.token || '' }}",
"lookupColumn": "token"
}
]
},
"sheetName": {
"__rl": true,
"mode": "name",
"value": "Sheet2"
},
"documentId": {
"__rl": true,
"mode": "url",
"value": "https://docs.google.com/spreadsheets/d/YOUR_SPREADSHEET_ID"
}
},
"typeVersion": 4.7,
"alwaysOutputData": true
},
{
"id": "dc27c8ff-75d6-4448-afb2-512d21cb08bf",
"name": "On form register",
"type": "n8n-nodes-base.formTrigger",
"position": [
224,
320
],
"parameters": {
"options": {
"path": "register"
},
"formTitle": "Register with your email",
"formFields": {
"values": [
{
"fieldLabel": "Email",
"requiredField": true
}
]
},
"formDescription": "Password will be sent to your email"
},
"typeVersion": 2.2
},
{
"id": "135c6108-45ec-45e6-b1e2-317e40a9004f",
"name": "Create password and token",
"type": "n8n-nodes-base.code",
"position": [
448,
320
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "function generatePassword(length = 12) {\n const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';\n let out = '';\n for (let i = 0; i < length; i++) {\n const idx = Math.floor(Math.random() * chars.length);\n out += chars[idx];\n }\n return out;\n}\nfunction makeToken(len = 32) {\n let out = '';\n while (out.length < len) {\n out += Math.random().toString(36).slice(2); // Strip the leading \"0.\"\n }\n return out.slice(0, len);\n}\nconst email = $json.Email\nconst password = generatePassword()\nconst token = makeToken()\nreturn {email, password, token};"
},
"typeVersion": 2
},
{
"id": "fec2646b-dd15-4e8c-ad07-9fa7de065c9a",
"name": "Send username/password",
"type": "n8n-nodes-base.gmail",
"position": [
928,
320
],
"parameters": {
"sendTo": "={{ $('Create password and token').item.json.email }}",
"message": "=Link to login: https://YOUR_DOMAIN/webhook/auth?token={{ $('Create password and token').item.json.token }}\n<br/>\nUsername: {{ $('Create password and token').item.json.email }}\n<br/>\nPassword: {{ $('Create password and token').item.json.password }}",
"options": {},
"subject": "=Your login credentials"
},
"typeVersion": 2.1
},
{
"id": "f3241140-939d-4871-8bf3-25dc9c69b653",
"name": "Notice register success",
"type": "n8n-nodes-base.form",
"position": [
1184,
320
],
"parameters": {
"options": {},
"operation": "completion",
"completionTitle": "Registration successful",
"completionMessage": "=<p><strong>\u2705 Please check email {{ $('Create password and token').item.json.email }} to get your login credentials</strong></p>\n<p>\n After that, you can login here:<br>\n <a href=\"https://YOUR_DOMAIN/form/login\" target=\"_blank\" rel=\"noopener noreferrer\">\n https://YOUR_DOMAIN/form/login\n </a>\n</p>"
},
"typeVersion": 1
},
{
"id": "3da0b92c-edad-43e2-bcf1-e7bca316d7e9",
"name": "On form login",
"type": "n8n-nodes-base.formTrigger",
"position": [
224,
736
],
"parameters": {
"options": {
"path": "login"
},
"formTitle": "Login",
"formFields": {
"values": [
{
"fieldLabel": "username",
"requiredField": true
},
{
"fieldType": "password",
"fieldLabel": "password",
"requiredField": true
}
]
}
},
"typeVersion": 2.2
},
{
"id": "caceffd3-862e-4ffc-817e-ed1300546caa",
"name": "Check username/password",
"type": "n8n-nodes-base.googleSheets",
"position": [
480,
736
],
"parameters": {
"options": {},
"filtersUI": {
"values": [
{
"lookupValue": "={{ $json.username }}",
"lookupColumn": "username"
},
{
"lookupValue": "={{ $json.password }}",
"lookupColumn": "password"
}
]
},
"sheetName": {
"__rl": true,
"mode": "name",
"value": "Sheet2"
},
"documentId": {
"__rl": true,
"mode": "url",
"value": "https://docs.google.com/spreadsheets/d/YOUR_SPREADSHEET_ID"
}
},
"typeVersion": 4.7,
"alwaysOutputData": true
},
{
"id": "91c227fd-ecbb-4d9f-a608-4606453a0e93",
"name": "If login success",
"type": "n8n-nodes-base.if",
"position": [
720,
736
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "455881ad-941f-4257-9427-1e48e7bc2974",
"operator": {
"type": "object",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $json }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "cedd4efe-c0e3-447b-a368-f4da51b0e004",
"name": "Redirect to login form",
"type": "n8n-nodes-base.form",
"position": [
992,
816
],
"parameters": {
"options": {},
"operation": "completion",
"redirectUrl": "=https://YOUR_DOMAIN/form/login",
"respondWith": "redirect"
},
"typeVersion": 1
},
{
"id": "6c2905c0-67d1-4c29-8ee5-3676d6ab1255",
"name": "Redirect to auth url",
"type": "n8n-nodes-base.form",
"position": [
1312,
624
],
"parameters": {
"options": {},
"operation": "completion",
"redirectUrl": "=https://YOUR_DOMAIN/webhook/auth?token={{ $json.token }}",
"respondWith": "redirect"
},
"typeVersion": 1
},
{
"id": "52426a88-2b8f-4839-b608-8c28e8cef5b1",
"name": "Add token to DB",
"type": "n8n-nodes-base.googleSheets",
"position": [
1568,
816
],
"parameters": {
"columns": {
"value": {
"token": "YOUR_CREDENTIAL_HERE",
"username": "={{ $('Check username/password').item.json.username }}"
},
"schema": [
{
"id": "username",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "username",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "role",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "role",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "password",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "password",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "token",
"type": "string",
"display": true,
"required": false,
"displayName": "token",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"username"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "name",
"value": "Sheet2"
},
"documentId": {
"__rl": true,
"mode": "url",
"value": "https://docs.google.com/spreadsheets/d/YOUR_SPREADSHEET_ID"
}
},
"typeVersion": 4.7
},
{
"id": "1a3c065f-b882-4088-9c34-5ebbb4fb787a",
"name": "Redirect to auth with new token",
"type": "n8n-nodes-base.form",
"position": [
1840,
816
],
"parameters": {
"options": {},
"operation": "completion",
"redirectUrl": "=https://YOUR_DOMAIN/webhook/auth?token={{ $('Generate token').item.json.token }}",
"respondWith": "redirect"
},
"typeVersion": 1
},
{
"id": "b4e2aebf-3f52-4234-ae86-f7c29f2a226d",
"name": "Auth",
"type": "n8n-nodes-base.webhook",
"position": [
208,
1200
],
"parameters": {
"path": "auth",
"options": {},
"responseMode": "responseNode"
},
"typeVersion": 2.1
},
{
"id": "340dcc3d-797c-44ca-a5ab-830687fbfffa",
"name": "Invalid token",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
736,
1344
],
"parameters": {
"options": {},
"respondWith": "text",
"responseBody": "Invalid token"
},
"typeVersion": 1.4
},
{
"id": "6119d68b-76d0-40ce-8ac1-df2253ca1a81",
"name": "If token valid",
"type": "n8n-nodes-base.if",
"position": [
976,
1184
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "a29fd91f-24e3-4302-9735-25419166511b",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $json.username }}",
"rightValue": ""
}
]
}
},
"executeOnce": true,
"typeVersion": 2.2
},
{
"id": "d3588bf0-be76-4e85-9ac4-ce11de129b25",
"name": "Redirect to login form1",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
1248,
1280
],
"parameters": {
"options": {},
"redirectURL": "={{ 'https://' + $('Auth').item.json.headers.host }}/form/login",
"respondWith": "redirect"
},
"typeVersion": 1.4
},
{
"id": "4d02d506-b001-45b8-afab-32ac76d29896",
"name": "Update sid",
"type": "n8n-nodes-base.googleSheets",
"position": [
1600,
1088
],
"parameters": {
"columns": {
"value": {
"sid": "={{ $json.sid }}",
"token": "",
"username": "={{ $('Search by token').item.json.username }}"
},
"schema": [
{
"id": "username",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "username",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "role",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "role",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "password",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "password",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "token",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "token",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "sid",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "sid",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "row_number",
"type": "number",
"display": true,
"removed": true,
"readOnly": true,
"required": false,
"displayName": "row_number",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"username"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "name",
"value": "Sheet2"
},
"documentId": {
"__rl": true,
"mode": "url",
"value": "https://docs.google.com/spreadsheets/d/YOUR_SPREADSHEET_ID"
}
},
"typeVersion": 4.7
},
{
"id": "0960c383-12b3-4176-8501-3b85d9453256",
"name": "Redirect to profile and set cookies",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
1600,
1280
],
"parameters": {
"options": {
"responseCode": 302,
"responseHeaders": {
"entries": [
{
"name": "Set-Cookie",
"value": "=sid={{$json.sid}}; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=604800"
},
{
"name": "Location",
"value": "/webhook/profile"
}
]
}
},
"respondWith": "text",
"responseBody": "={{ $json.sid }}"
},
"typeVersion": 1.4
},
{
"id": "ed4908f3-50f0-4150-adbc-ca5b706a94e3",
"name": "Profile",
"type": "n8n-nodes-base.webhook",
"position": [
224,
1712
],
"parameters": {
"path": "profile",
"options": {},
"responseMode": "responseNode"
},
"typeVersion": 2.1
},
{
"id": "2d514f17-01f8-4410-a759-50289488502f",
"name": "Check sid cookies header",
"type": "n8n-nodes-base.code",
"position": [
448,
1712
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "function getCookie(headers, name) {\n const raw = (headers.cookie || headers.Cookie || \"\");\n if (!raw) return null;\n\n const parts = raw.split(\";\").map(s => s.trim());\n for (const p of parts) {\n const eq = p.indexOf(\"=\");\n if (eq === -1) continue;\n const k = p.slice(0, eq).trim();\n const v = p.slice(eq + 1).trim();\n if (k === name) return decodeURIComponent(v);\n }\n return null;\n}\n\nconst headers = $json.headers || {};\nconst sid = getCookie(headers, \"sid\");\n\nreturn {\n json: {\n sid,\n hasCookieHeader: !!(headers.cookie || headers.Cookie),\n }\n};\n"
},
"typeVersion": 2
},
{
"id": "9d062264-f2c0-4659-b68f-714b03389ac4",
"name": "Search sid",
"type": "n8n-nodes-base.googleSheets",
"position": [
672,
1712
],
"parameters": {
"options": {},
"filtersUI": {
"values": [
{
"lookupValue": "={{ $json.sid || '' }}",
"lookupColumn": "sid"
}
]
},
"sheetName": {
"__rl": true,
"mode": "name",
"value": "Sheet2"
},
"documentId": {
"__rl": true,
"mode": "url",
"value": "https://docs.google.com/spreadsheets/d/YOUR_SPREADSHEET_ID"
}
},
"typeVersion": 4.7,
"alwaysOutputData": true
},
{
"id": "d7dd2d42-a6bf-4adb-9571-1736cdb11703",
"name": "If has data with sid",
"type": "n8n-nodes-base.if",
"position": [
880,
1712
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "a29fd91f-24e3-4302-9735-25419166511b",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $json.username }}",
"rightValue": ""
}
]
}
},
"executeOnce": true,
"typeVersion": 2.2
},
{
"id": "89d72c2d-0f9a-4e63-a1e0-7245cdafad39",
"name": "Redirect to login",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
1168,
1808
],
"parameters": {
"options": {},
"redirectURL": "={{ 'https://' + $('Profile').item.json.headers.host }}/form/login",
"respondWith": "redirect"
},
"typeVersion": 1.4
},
{
"id": "e13952a5-dc41-4429-a0ba-bb918e18e41f",
"name": "Prepare html",
"type": "n8n-nodes-base.code",
"position": [
1168,
1568
],
"parameters": {
"jsCode": "const html = `Hello ${$input.first().json.username}`;\n\nreturn { json: { html } };\n"
},
"typeVersion": 2
},
{
"id": "bbb5e14a-e5f1-4eff-acb0-e02203922a70",
"name": "Show profile page",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
1392,
1568
],
"parameters": {
"options": {},
"respondWith": "text",
"responseBody": "={{ $json.html }}"
},
"typeVersion": 1.4
},
{
"id": "9496073d-aaa6-4d65-a2d5-a4ee7cd3c85c",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-896,
576
],
"parameters": {
"width": 880,
"height": 720,
"content": "## Overview\nThis workflow provides a lightweight authentication flow for n8n web portals using Google Sheets as a simple user/session store and email delivery for onboarding. It supports register, username/password login, one-click magic link auth, and a cookie-based profile page.\n\n### How it works\n1. User registers with an email address via a form\n2. n8n generates a username, password, and a one-time auth token\n3. User data is stored in Google Sheets\n4. n8n sends an email containing credentials + a one-click login link (`/auth?token=...`)\n5. User can log in with username/password or click the magic link\n6. `/auth` validates the token, creates a session id (sid), sets it as an HttpOnly cookie, and invalidates the token\n7. `/profile` reads the sid cookie, validates the session in Google Sheets, and displays user info to confirm login\n\n### Setup\n- Configure Gmail credentials in the Send email node\n- Create a Google Sheet with columns: username, password, role, token, sid\n- Add your Google Sheets URL (replace YOUR_SPREADSHEET_ID)\n- Replace YOUR_DOMAIN with your n8n instance domain in all nodes\n- Ensure your n8n instance is served over HTTPS so Secure cookies work\n\n### Customization\n- Adjust token expiry (e.g., 10-15 minutes) and one-time use behavior\n- Change session cookie settings (name, Max-Age, SameSite)\n- Customize the registration email content\n- Replace the Profile HTML with your own portal UI\n- Add a /logout endpoint to revoke sessions\n- Add rate-limiting at reverse proxy (Nginx/Traefik/Cloudflare)\n"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "b1b52d4f-9d40-40ce-b044-44d951a1bfb7",
"connections": {
"Auth": {
"main": [
[
{
"node": "If has token",
"type": "main",
"index": 0
}
]
]
},
"Profile": {
"main": [
[
{
"node": "Check sid cookies header",
"type": "main",
"index": 0
}
]
]
},
"Search sid": {
"main": [
[
{
"node": "If has data with sid",
"type": "main",
"index": 0
}
]
]
},
"Prepare sid": {
"main": [
[
{
"node": "Redirect to profile and set cookies",
"type": "main",
"index": 0
},
{
"node": "Update sid",
"type": "main",
"index": 0
}
]
]
},
"If has token": {
"main": [
[
{
"node": "Search by token",
"type": "main",
"index": 0
}
],
[
{
"node": "Invalid token",
"type": "main",
"index": 0
}
]
]
},
"Prepare html": {
"main": [
[
{
"node": "Show profile page",
"type": "main",
"index": 0
}
]
]
},
"On form login": {
"main": [
[
{
"node": "Check username/password",
"type": "main",
"index": 0
}
]
]
},
"Generate token": {
"main": [
[
{
"node": "Add token to DB",
"type": "main",
"index": 0
}
]
]
},
"If token valid": {
"main": [
[
{
"node": "Prepare sid",
"type": "main",
"index": 0
}
],
[
{
"node": "Redirect to login form1",
"type": "main",
"index": 0
}
]
]
},
"Add token to DB": {
"main": [
[
{
"node": "Redirect to auth with new token",
"type": "main",
"index": 0
}
]
]
},
"Search by token": {
"main": [
[
{
"node": "If token valid",
"type": "main",
"index": 0
}
]
]
},
"If login success": {
"main": [
[
{
"node": "If has token in DB",
"type": "main",
"index": 0
}
],
[
{
"node": "Redirect to login form",
"type": "main",
"index": 0
}
]
]
},
"On form register": {
"main": [
[
{
"node": "Create password and token",
"type": "main",
"index": 0
}
]
]
},
"If has token in DB": {
"main": [
[
{
"node": "Redirect to auth url",
"type": "main",
"index": 0
}
],
[
{
"node": "Generate token",
"type": "main",
"index": 0
}
]
]
},
"If has data with sid": {
"main": [
[
{
"node": "Prepare html",
"type": "main",
"index": 0
}
],
[
{
"node": "Redirect to login",
"type": "main",
"index": 0
}
]
]
},
"Send username/password": {
"main": [
[
{
"node": "Notice register success",
"type": "main",
"index": 0
}
]
]
},
"Check username/password": {
"main": [
[
{
"node": "If login success",
"type": "main",
"index": 0
}
]
]
},
"Check sid cookies header": {
"main": [
[
{
"node": "Search sid",
"type": "main",
"index": 0
}
]
]
},
"Create password and token": {
"main": [
[
{
"node": "Append or update row in sheet",
"type": "main",
"index": 0
}
]
]
},
"Append or update row in sheet": {
"main": [
[
{
"node": "Send username/password",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow implements a lightweight authentication system for n8n web portals using Google Sheets as a simple user and session store. It supports email-based registration, username and password login, one-click magic link authentication, and cookie-based session management.
Source: https://n8n.io/workflows/13703/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Tags: Supply Chain Management, Logistics, Transportation
This n8n workflow enables teams to automate and standardize multi-step onboarding or messaging workflows using Google Sheets, Forms, Gmail, and dynamic logic powered by Code and Switch nodes. It ensur
This workflow automates the process of retrieving Stripe invoices, validating API responses, generating payment receipts, sending them via email, storing PDFs in Google Drive, and appending details to
This workflow is triggered when the contact form is submitted.
Filter Summarize. Uses googleSheetsTool, formTrigger, stickyNote, form. Event-driven trigger; 20 nodes.