Panel de autenticación (registro/inicio sesión/olvidé la contraseña)
Este es unEngineeringflujo de automatización del dominio deautomatización que contiene 16 nodos.Utiliza principalmente nodos como If, Switch, Webhook, Postgres, RespondToWebhook. Usar PostgreSQL y Webhooks para crear un sistema completo de autenticación de usuarios
- •Punto final de HTTP Webhook (n8n generará automáticamente)
- •Información de conexión de la base de datos PostgreSQL
Nodos utilizados (16)
Categoría
{
"id": "cIhoaw0VJGihOHmy",
"meta": {
"instanceId": "deff2e7875268ae3fbe0cda0c3aa28feebb743b5a609a8cf33e4b05565651d9c",
"templateCredsSetupCompleted": true
},
"name": "Authentication Panel (Signup/Login/Forgot Password)",
"tags": [],
"nodes": [
{
"id": "e430c384-eec7-4c18-a105-ae8d4d5216bc",
"name": "Resumen",
"type": "n8n-nodes-base.stickyNote",
"position": [
176,
1568
],
"parameters": {
"color": 5,
"width": 600,
"height": 640,
"content": "## Overview: Authentication\n**Purpose:** Manages user signup, login, and password reset via a single webhook.\n**Features:**\n- **Signup:** Creates new users with bcrypt-hashed passwords.\n- **Login:** Verifies credentials case-insensitively.\n- **Forgot Password:** Generates and returns a new random password.\n**Prerequisites:**\n- PostgreSQL/Supabase with `users` table.\n- Enable `uuid-ossp` and `pgcrypto` extensions.\n- Set PostgreSQL credentials in n8n.\n**Usage:** POST to `/webhook/auth` with:\n```json\n{ \"path\": \"signup|signin|forgot\", \"email\": \"string\", \"password\": \"string\", \"name\": \"string\" }\n```\n**Example:** `{\"path\": \"signup\", \"email\": \"user@example.com\", \"password\": \"pass123\", \"name\": \"John Doe\"}`\n**Output:** `{\"status\": \"success|error\", \"message\": \"string\", \"data\": {}}`"
},
"typeVersion": 1
},
{
"id": "a81f1cc2-4d7b-4d71-a103-667f43724c17",
"name": "Webhook Doc",
"type": "n8n-nodes-base.stickyNote",
"position": [
816,
1568
],
"parameters": {
"color": 5,
"width": 624,
"height": 464,
"content": "## Webhook: Entry Point\n**Purpose:** Handles all auth requests via POST.\n**Endpoint:** `/webhook/auth`\n**Input JSON:**\n```json\n{ \"path\": \"signup|signin|forgot\", \"email\": \"string\", \"password\": \"string\", \"name\": \"string\" }\n```\n**Notes:**\n- `path` routes to signup, login, or forgot password.\n- Only POST method supported."
},
"typeVersion": 1
},
{
"id": "ee0f4193-74e8-4df4-ba1e-09950cc38dfe",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
1104,
1856
],
"webhookId": "d670d0e6-ac14-4b3f-b556-593969c1c8f2",
"parameters": {
"path": "auth",
"options": {},
"httpMethod": "POST",
"responseMode": "responseNode"
},
"typeVersion": 2.1
},
{
"id": "1a42c7bc-b3ff-4495-8207-cffe9c2edc70",
"name": "Switch Doc",
"type": "n8n-nodes-base.stickyNote",
"position": [
1456,
1568
],
"parameters": {
"color": 5,
"width": 528,
"height": 472,
"content": "## Switch: Route Actions\n**Purpose:** Routes requests based on `path`.\n**Rules:**\n- `signup` → Signup\n- `signin` → Login\n- `forgot` → Forgot Password\n**Default:** No action for invalid `path`.\n**Notes:** Ensure `path` is lowercase."
},
"typeVersion": 1
},
{
"id": "e4b6610a-5fcc-4dea-82d7-b8388ba39cdc",
"name": "Router",
"type": "n8n-nodes-base.switch",
"position": [
1648,
1824
],
"parameters": {
"rules": {
"rules": [
{
"output": 1,
"value2": "signup"
},
{
"output": 2,
"value2": "signin"
},
{
"output": 3,
"value2": "forgot"
}
]
},
"value1": "={{$json[\"path\"]}}",
"dataType": "string",
"fallbackOutput": 0
},
"typeVersion": 1
},
{
"id": "68549d4c-294a-4a74-a849-ee87814334fb",
"name": "Signup Doc",
"type": "n8n-nodes-base.stickyNote",
"position": [
2000,
1568
],
"parameters": {
"color": 6,
"width": 580,
"height": 472,
"content": "## PostgreSQL: Signup\n**Purpose:** Creates a new user.\n**SQL:**\n```sql\nINSERT INTO users (full_name, email, password_hash)\nVALUES ('{{$json[\"name\"]}}', '{{$json[\"email\"]}}', crypt('{{$json[\"password\"]}}', gen_salt('bf')))\nRETURNING id, full_name, email, created_at;\n```\n**Output:** `{ id, full_name, email, created_at }`\n**Notes:**\n- Uses bcrypt for password hashing.\n- Requires unique email in `users` table."
},
"typeVersion": 1
},
{
"id": "2dd10f62-a7af-4ed3-bbf9-acb3ab00a5c7",
"name": "Registro",
"type": "n8n-nodes-base.postgres",
"position": [
2352,
1888
],
"parameters": {
"query": "INSERT INTO users (full_name, email, password_hash)\nVALUES (\n '{{$json[\"name\"]}}',\n '{{$json[\"email\"]}}',\n crypt('{{$json[\"password\"]}}', gen_salt('bf'))\n)\nRETURNING id, full_name, email, created_at;\n",
"options": {},
"operation": "executeQuery"
},
"credentials": {
"postgres": {
"id": "RCxqFMerFYoFK91z",
"name": "Project: Edubot"
}
},
"typeVersion": 2.6
},
{
"id": "2ded10d4-9715-4a06-991a-b5224039f5aa",
"name": "Login Doc",
"type": "n8n-nodes-base.stickyNote",
"position": [
832,
2096
],
"parameters": {
"color": 6,
"width": 532,
"height": 600,
"content": "## PostgreSQL: Login\n**Purpose:** Verifies user credentials.\n**SQL:**\n```sql\nSELECT\n id,\n full_name,\n email,\n (password_hash = crypt('{{$json[\"password\"]}}', password_hash)) AS \"isPasswordMatch\"\nFROM users\nWHERE LOWER(email) = LOWER('{{$json[\"email\"]}}');\n```\n**Output:** `{ id, full_name, email, isPasswordMatch }`\n**Notes:**\n- Case-insensitive email check.\n- `isPasswordMatch` confirms correct password."
},
"typeVersion": 1
},
{
"id": "7cb04861-2a0b-4298-b050-f6fd232439e1",
"name": "Inicio de Sesión",
"type": "n8n-nodes-base.postgres",
"position": [
864,
2528
],
"parameters": {
"query": "SELECT\n id,\n full_name,\n email,\n (password_hash = crypt('{{$json[\"password\"]}}', password_hash)) AS \"isPasswordMatch\"\nFROM users\nWHERE LOWER(email) = LOWER('{{$json[\"email\"]}}');\n",
"options": {},
"operation": "executeQuery"
},
"credentials": {
"postgres": {
"id": "RCxqFMerFYoFK91z",
"name": "Project: Edubot"
}
},
"typeVersion": 2.6
},
{
"id": "d189c3bf-9e95-4666-b205-50734ee47821",
"name": "IF Doc",
"type": "n8n-nodes-base.stickyNote",
"position": [
1392,
2096
],
"parameters": {
"color": 6,
"width": 400,
"height": 600,
"content": "## IF: Validate Login\n**Purpose:** Checks if login is valid.\n**Condition:** `id` exists and `isPasswordMatch` is `true`.\n**Outputs:**\n- True → Success response.\n- False → Error response (invalid credentials).\n**Notes:** Ensures only valid users proceed."
},
"typeVersion": 1
},
{
"id": "b154b3cb-d21e-4451-b526-fca72281d0ab",
"name": "Verificar Inicio de Sesión",
"type": "n8n-nodes-base.if",
"position": [
1504,
2528
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "41d2a73b-ece5-4043-894a-ab8bf12e55b3",
"operator": {
"type": "boolean",
"operation": "equal"
},
"leftValue": "={{ $json[\"id\"] !== undefined && $json[\"isPasswordMatch\"] === true }}",
"rightValue": "true"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "f7b96eac-f2a1-489c-92e5-10ab62244003",
"name": "Forgot Password Doc",
"type": "n8n-nodes-base.stickyNote",
"position": [
1808,
2096
],
"parameters": {
"color": 6,
"width": 580,
"height": 608,
"content": "## PostgreSQL: Forgot Password\n**Purpose:** Resets password to a random 8-char string.\n**SQL:**\n```sql\nWITH new_pass AS (\n SELECT substring(md5(random()::text) from 1 for 8) AS plain_password\n)\nUPDATE users\nSET password_hash = crypt(new_pass.plain_password, gen_salt('bf'))\nFROM new_pass\nWHERE LOWER(email) = LOWER('{{$json[\"email\"]}}')\nRETURNING email, new_pass.plain_password AS newPassword;\n```\n**Output:** `{ email, newPassword }`\n**Notes:**\n- Case-insensitive email.\n- New password can be emailed."
},
"typeVersion": 1
},
{
"id": "360ce51c-db91-46ec-841e-518abb068712",
"name": "Restablecer Contraseña",
"type": "n8n-nodes-base.postgres",
"position": [
2144,
2416
],
"parameters": {
"query": "WITH new_pass AS (\n SELECT substring(md5(random()::text) from 1 for 8) AS plain_password\n)\nUPDATE users\nSET password_hash = crypt(new_pass.plain_password, gen_salt('bf'))\nFROM new_pass\nWHERE LOWER(email) = LOWER('{{$json[\"email\"]}}')\nRETURNING email, new_pass.plain_password AS newPassword;\n",
"options": {},
"operation": "executeQuery"
},
"credentials": {
"postgres": {
"id": "RCxqFMerFYoFK91z",
"name": "Project: Edubot"
}
},
"typeVersion": 2.6
},
{
"id": "0a9bf2d6-a7ff-47e4-874f-b6ad0274199c",
"name": "Response Doc",
"type": "n8n-nodes-base.stickyNote",
"position": [
2432,
2096
],
"parameters": {
"color": 5,
"width": 688,
"height": 600,
"content": "## Respond: Send Response\n**Purpose:** Returns JSON response.\n**Format:**\n```json\n{\n \"status\": \"success|error\",\n \"message\": \"string\",\n \"data\": {}\n}\n```\n**Notes:**\n- Success: Returns query results.\n- Error: Handles invalid inputs or failures."
},
"typeVersion": 1
},
{
"id": "cef94eb3-936a-496a-a950-90c8708ec56a",
"name": "Responder",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
2848,
2544
],
"parameters": {
"options": {}
},
"typeVersion": 1.4
},
{
"id": "b5d535cc-a1a0-4674-b56f-4f9f2fd6a08d",
"name": "Configuración de Base de Datos",
"type": "n8n-nodes-base.stickyNote",
"position": [
176,
2240
],
"parameters": {
"color": 5,
"width": 600,
"height": 480,
"content": "## Database Setup\n**Purpose:** Configure PostgreSQL/Supabase.\n**Steps:**\n1. Create Supabase project at [supabase.com](https://supabase.com).\n2. Enable extensions: `uuid-ossp`, `pgcrypto`.\n3. Create `users` table:\n```sql\nCREATE TABLE users (\n id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),\n full_name text NOT NULL,\n email text UNIQUE NOT NULL,\n password_hash text NOT NULL,\n created_at timestamptz DEFAULT now()\n);\n```\n4. Add PostgreSQL credentials in n8n.\n**Notes:** Ensure unique email constraint."
},
"typeVersion": 1
}
],
"active": false,
"pinData": {
"Webhook": [
{
"json": {
"path": "forgot",
"email": "ali.raza@example.com"
}
}
]
},
"settings": {
"executionOrder": "v1"
},
"versionId": "e51c5384-1056-4f65-a0f1-187b68971e0e",
"connections": {
"7cb04861-2a0b-4298-b050-f6fd232439e1": {
"main": [
[
{
"node": "b154b3cb-d21e-4451-b526-fca72281d0ab",
"type": "main",
"index": 0
}
]
]
},
"e4b6610a-5fcc-4dea-82d7-b8388ba39cdc": {
"main": [
[],
[
{
"node": "2dd10f62-a7af-4ed3-bbf9-acb3ab00a5c7",
"type": "main",
"index": 0
}
],
[
{
"node": "7cb04861-2a0b-4298-b050-f6fd232439e1",
"type": "main",
"index": 0
}
],
[
{
"node": "360ce51c-db91-46ec-841e-518abb068712",
"type": "main",
"index": 0
}
]
]
},
"2dd10f62-a7af-4ed3-bbf9-acb3ab00a5c7": {
"main": [
[
{
"node": "cef94eb3-936a-496a-a950-90c8708ec56a",
"type": "main",
"index": 0
}
]
]
},
"ee0f4193-74e8-4df4-ba1e-09950cc38dfe": {
"main": [
[
{
"node": "e4b6610a-5fcc-4dea-82d7-b8388ba39cdc",
"type": "main",
"index": 0
}
]
]
},
"b154b3cb-d21e-4451-b526-fca72281d0ab": {
"main": [
[
{
"node": "cef94eb3-936a-496a-a950-90c8708ec56a",
"type": "main",
"index": 0
}
],
[
{
"node": "cef94eb3-936a-496a-a950-90c8708ec56a",
"type": "main",
"index": 0
}
]
]
},
"360ce51c-db91-46ec-841e-518abb068712": {
"main": [
[
{
"node": "cef94eb3-936a-496a-a950-90c8708ec56a",
"type": "main",
"index": 0
}
]
]
}
}
}¿Cómo usar este flujo de trabajo?
Copie el código de configuración JSON de arriba, cree un nuevo flujo de trabajo en su instancia de n8n y seleccione "Importar desde JSON", pegue la configuración y luego modifique la configuración de credenciales según sea necesario.
¿En qué escenarios es adecuado este flujo de trabajo?
Avanzado - Ingeniería
¿Es de pago?
Este flujo de trabajo es completamente gratuito, puede importarlo y usarlo directamente. Sin embargo, tenga en cuenta que los servicios de terceros utilizados en el flujo de trabajo (como la API de OpenAI) pueden requerir un pago por su cuenta.
Flujos de trabajo relacionados recomendados
Convosoft
@convosoftCompartir este flujo de trabajo