create account

Hive Tutorials Auth Login Keychain React Fullstack | english/spanish by theghost1980

View this thread on: hive.blogpeakd.comecency.com
· @theghost1980 ·
$12.55
Hive Tutorials Auth Login Keychain React Fullstack | english/spanish
![hive-tuts-base.jpg](https://files.peakd.com/file/peakd-hive/theghost1980/AK28WwbrnospvWyvzep8kA8j5ws9yiozkkEAk1zwED9t6BJ7PCoQxH54jWakVwa.jpg)

Saludos Hivers, por aca les traigo una nueva entrega para seguir con los tutoriales de Hive & React. En este articulo veremos como crear algo en el reino de lo que llamamos [Fullstack](https://santandersmartbank.es/talent-scanner/tecnologia-y-data/full-stack-developer/) y trata de como autenticar usando Hive Keychain.

Link al repositorio principal del tutorial completo >> [aqui](https://github.com/theghost1980/react-hive-tutorials?tab=readme-ov-file) <<

-----
🧩 Proceso de Inicio de Sesión con Hive Keychain
1. Instalación de Hive Keychain
El usuario instala la extensión Hive Keychain en su navegador compatible.

2. Importación de la Cuenta Hive
Se importan las claves privadas del usuario en la extensión para habilitar la firma de transacciones.

3. Interfaz de Inicio de Sesión
La aplicación presenta un botón o formulario para que el usuario inicie sesión con su nombre de usuario de Hive.

4. Generación de Mensaje Único
La aplicación genera un mensaje único, como una marca de tiempo, para prevenir ataques de repetición.

5. Solicitud de Firma con Hive Keychain
Se utiliza la función requestSignBuffer para solicitar al usuario que firme el mensaje a través de Hive Keychain.

6. Firma del Mensaje
El usuario aprueba la solicitud en la extensión, que firma el mensaje con su clave privada de publicación.

7. Envío al Servidor para Verificación
La aplicación envía el nombre de usuario, el mensaje y la firma al servidor backend para su verificación.

8. Obtención de Clave Pública desde la Blockchain
El servidor recupera la clave pública de publicación del usuario desde la blockchain de Hive.

9. Verificación de la Firma
El servidor utiliza la clave pública para verificar que la firma corresponde al mensaje original.

10. Confirmación de Autenticación Exitosa
Si la firma es válida, el servidor responde afirmativamente, y el usuario es considerado autenticado.

> Este proceso garantiza una autenticación segura y descentralizada sin necesidad de compartir contraseñas o claves privadas directamente con la aplicación.
-----

> English at the bottom

## Frontend: Cliente
---
### 🛠️ Configuración del Proyecto
- Crear el Proyecto con Vite
- Creamos la carpeta para el client y nos movemos a la carpeta:
`mkdir client && cd client`
- Ejecuta el siguiente comando para crear un nuevo proyecto con Vite y React utilizando TypeScript:
```
npm create vite@latest . -- --template react-ts
```
### Instalar Dependencias Adicionales
- Instalemos keychain-helper para ayudarnos a interactuar con la Hive Keychain
`npm i keychain-helper`
- Creamos una carpeta dentro de `/src/` y la llamamos `components` y dentro creamos el archivo Login.tsx:
```
import React from 'react';
import {KeychainHelper} from 'keychain-helper';

const Login: React.FC = () => {
  const handleLogin = async () => {
    const username = prompt('Ingrese su nombre de usuario de Hive:');
    if (!username) return;

    const message = `Autenticación con Hive Keychain - ${new Date().toISOString()}`;
    KeychainHelper.requestLogin(username,message, async (keychainResponse) => {
        if(keychainResponse.success){
            //continue to send info to backend for verification.
            const responseBE = await fetch('http://localhost:6001/verify', {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                },
                body: JSON.stringify({
                    username, message, signature: keychainResponse.result
                }),
            });
            if(responseBE.status === 200){ //{ success: true, message: 'Firma válida' }
                const result = await responseBE.json();
                if(result.success && result.message === "Firma válida"){
                    alert('Autenticado con exito! Ahora puedes codificar las rutas protegidas y demas!');
                }else{
                    console.log('No se autentico: ',{result});
                }
            }
        }else{
            console.log({keychainResponse}); 
        }
    });
  }; 

  return (
    <div>
      <h2>Iniciar Sesión con Hive Keychain</h2>
      <button onClick={handleLogin}>Iniciar Sesión</button>
    </div>
  );
};

export default Login;

```
- Usamos login en App.tsx y podemos remover todo el codigo por defecto, nos quedaria asi:
```
import './App.css'
import Login from './components/Login'

function App() {
  return (
    <>
      <Login />
    </>
  )
}

export default App
```
- Iniciamos la App(Ojo el servidor ya debe estar corriendo) y usamos:
`npm run dev`
- Deberias ver algo como esto al ejecutar tu frontend:

![image.png](https://files.peakd.com/file/peakd-hive/theghost1980/Eo2BpKHNqwzA6mTZQaxqSFZ5wVgqggNaichpFcfuDa6Siu9GRGTETMz1BcRzaGsfLdo.png)



> Nota: Hive Keychain debe estar instalado para poder interactuar con la firma del mensaje. Mas info aca: https://hive-keychain.com/

---

### Backend: servidor
---

> Nota importante: siempre que veas una linea de comandos con multiples comandos, puedes ejecutar 1 por una y asi sabras lo que cada una hace o simplemente corre todo a la vez.

### 🔐 Implementación del Backend
- Configurar el Servidor con Express
- Ejecutamos uno a uno, estos comandos si iniciamos el proyecto desde cero:
```
mkdir server 
cd server
npm init -y
npm install express@^4.17.1 cors body-parser dhive
npm install --save-dev typescript @types/express@^4.17.13 @types/node @types/body-parser ts-node nodemon @types/cors
```
Lo que hicimos fue:
1. Crear el directorio server
2. Nos movemos a server
3. Inicializamos usando npm, eso nos crea un archivo package.json con la informacion por defecto
4. Instalamos dependencias para express que hacen:
    - cors(que nos permite probar el servidor localmente sin uso de https) 
    - body-parser(procesar los datos enviados en el "cuerpo" de las peticiones HTTP entrantes)
    - dhive(libreria para interactuar con la HIVE blockchain y funciones utiles)
5. Instalamos ademas dependencias de desarrollo que son tipos y declaraciones necesarias para typescript.

> Nota decidi dejar esas versiones para express y sus tipos ya que para versiones mas recientes a veces causa errores en desarrollo.
---

- Crea un archivo tsconfig.json en la carpeta server con la configuración básica de TypeScript.
```
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "outDir": "dist",
    "rootDir": "src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true
  },
}
```
### Implementar la Ruta de Verificación
En el archivo server/index.ts, implementa una ruta para verificar la firma:
```
import express, {Request,Response} from 'express';
import cors from 'cors';
import bodyParser from 'body-parser';
import { Client, PublicKey, Signature, cryptoUtils } from '@hiveio/dhive';

const app = express();
app.use(cors());
app.use(bodyParser.json());

const client = new Client(['https://api.hive.blog']);

app.post('/verify', async (req: Request, res: Response) => {
  // Datos recibidos del cliente
const { username, message, signature: signatureStr } = req.body;

try {
  // Obtener la clave pública del usuario desde la blockchain
  const account = await client.database.getAccounts([username]);
  if (!account || account.length === 0) {
    return res.status(404).json({ error: 'Usuario no encontrado' });
  }

  const publicKeyData = account[0].posting.key_auths[0][0];
  const publicKeyStr = typeof publicKeyData === 'string' ? publicKeyData : publicKeyData.toString();

  // Crear instancias de PublicKey y Signature
  const publicKey = PublicKey.fromString(publicKeyStr);
  const signature = Signature.fromString(signatureStr);

  // Calcular el hash del mensaje
  const messageHash = cryptoUtils.sha256(message);

  // Verificar la firma
  const isValid = publicKey.verify(messageHash, signature);

  if (isValid) {
    res.status(200).json({ success: true, message: 'Firma válida' });
  } else {
    res.status(401).json({ success: false, message: 'Firma inválida' });
  }
} catch (error) {
  console.error('Error al verificar la firma:', error);
  res.status(500).json({ error: 'Error interno del servidor' });
}
});

app.listen(6001, () => {
  console.log('Servidor backend ejecutándose en http://localhost:6001');
});
```

### 🧪 Prueba/Puesta en marcha de la Aplicación
- Ejecuta `npx ts-node index.ts`
Deberias ver algo como esto en tu consola de VSCode:

![image.png](https://files.peakd.com/file/peakd-hive/theghost1980/23t74tV4g6vDzGEwkqjRrhS7UhLTZX2WjwHjs5ovLxs9kwoETsGcfTwc4yV9VzR6cYjMZ.png)


## Pro-tip
Siempre inicia el backend primero. No necesitas abrir varios editores de VScode, simpelemte, debajo en la seccion de terminales abre al menos 2. Y vas navegando usando los comandos `ls` `cd` para moverte a la carpeta client y al server.
> De esta manera puede ejecutar cada parte en una consola por separado.

### Si todo marcha como debería, al hacer login sucedera esto:

![image.png](https://files.peakd.com/file/peakd-hive/theghost1980/23rB9Ruc4tg55s7AorisQ32mc39K4XK8z4hbTDdVdkMjfv8Fk4jKzKjZ3g28jJe2iVPDR.png)


![image.png](https://files.peakd.com/file/peakd-hive/theghost1980/246GKuDiAoFF8QbW5dVTxrBCroUuuuceHczJYafFptk2ViPtjZmaeGLq29u5Aym5jHgrn.png)


![image.png](https://files.peakd.com/file/peakd-hive/theghost1980/244UoTZPXQHsmotSQpqb1DYDKUmw4tvuLtjqCnHaWtwHtNiFcSJtf5RHCg74QkbB7jbwo.png)


<details>
<summary>English Version Here</summary>

Greetings Hivers, here I bring you a new installment to continue with the Hive & React tutorials. In this article, we will explore creating something in the realm of what we call [Fullstack](https://santandersmartbank.es/talent-scanner/tecnologia-y-data/full-stack-developer/), focusing on authentication using Hive Keychain.

## Frontend: Client

---
Certainly! Here's the translated and formatted markdown content for the login process using Hive Keychain:

---

## 🧩 Hive Keychain Login Process

1. **Install Hive Keychain Extension**
   The user installs the Hive Keychain extension on a compatible browser (e.g., Chrome, Firefox).

2. **Import Hive Account**
   The user imports their Hive account into the extension using the "Use keys/pwd" option. 

3. **Enter Hive Credentials**
   The user enters their Hive username and master password to import their keys.

4. **Set Up Keychain Password**
   The user sets a unique password for the Hive Keychain extension on their device.

5. **Access dApp Login Interface**
   The user navigates to the decentralized application's login interface that supports Hive Keychain.

6. **Initiate Login Request**
   The dApp prompts the user to log in, triggering Hive Keychain to open a signature request.

7. **Sign Authentication Message**
   The user reviews and signs the authentication message using their posting key via Hive Keychain.

8. **Send Signature to Backend**
   The dApp sends the signed message and username to the backend server for verification.

9. **Verify Signature on Server**
   The backend retrieves the user's public key from the Hive blockchain and verifies the signature.

10. **Confirm Successful Authentication**
    If the signature is valid, the server confirms authentication, granting the user access to the dApp.

> This process ensures secure and decentralized authentication without exposing private keys or passwords.

---

## 🛠️ Project Setup

* Create the Project with Vite
* Create the folder for the client and navigate into it:

  ```bash
  mkdir client && cd client
  ```
* Run the following command to create a new project with Vite and React using TypeScript:

  ```bash
  npm create vite@latest . -- --template react-ts
  ```

## Install Additional Dependencies

* Install `keychain-helper` to assist in interacting with Hive Keychain:

  ```bash
  npm i keychain-helper
  ```

* Create a folder inside `/src/` named `components` and within it, create the file `Login.tsx`:

  ```tsx
  import React from 'react';
  import { KeychainHelper } from 'keychain-helper';

  const Login: React.FC = () => {
    const handleLogin = async () => {
      const username = prompt('Enter your Hive username:');
      if (!username) return;

      const message = `Authentication with Hive Keychain - ${new Date().toISOString()}`;
      KeychainHelper.requestLogin(username, message, async (keychainResponse) => {
        if (keychainResponse.success) {
          // Continue to send info to backend for verification.
          const responseBE = await fetch('http://localhost:6001/verify', {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
            },
            body: JSON.stringify({
              username,
              message,
              signature: keychainResponse.result
            }),
          });
          if (responseBE.status === 200) {
            const result = await responseBE.json();
            if (result.success && result.message === "Valid signature") {
              alert('Successfully authenticated! Now you can code protected routes and more!');
            } else {
              console.log('Authentication failed: ', { result });
            }
          }
        } else {
          console.log({ keychainResponse });
        }
      });
    };

    return (
      <div>
        <h2>Log In with Hive Keychain</h2>
        <button onClick={handleLogin}>Log In</button>
      </div>
    );
  };

  export default Login;
  ```

* Use the `Login` component in `App.tsx` and remove all default code, resulting in:

  ```tsx
  import './App.css'
  import Login from './components/Login'

  function App() {
    return (
      <>
        <Login />
      </>
    )
  }

  export default App
  ```

* Start the App (ensure the server is already running) using:

  ```bash
  npm run dev
  ```

> Note: Hive Keychain must be installed to interact with message signing. More info here: [https://hive-keychain.com/](https://hive-keychain.com/)

---

## Backend: Server

---

> Important Note: Whenever you see a command line with multiple commands, you can execute them one by one to understand what each does, or simply run them all at once.

## 🔐 Backend Implementation

* Set up the Server with Express
* Execute the following commands one by one if starting the project from scratch:

  ```bash
  mkdir server 
  cd server
  npm init -y
  npm install express@^4.17.1 cors body-parser dhive
  npm install --save-dev typescript @types/express@^4.17.13 @types/node @types/body-parser ts-node nodemon @types/cors
  ```

  What we did:

  1. Created the `server` directory
  2. Navigated into `server`
  3. Initialized with npm, creating a `package.json` file with default information
  4. Installed dependencies for Express:

     * `cors` (allows us to test the server locally without using HTTPS)
     * `body-parser` (processes data sent in the body of incoming HTTP requests)
     * `dhive` (library to interact with the HIVE blockchain and useful functions)
  5. Additionally installed development dependencies which are types and declarations necessary for TypeScript.

> Note: I chose to use these versions for Express and its types because newer versions sometimes cause development errors.

---

* Create a `tsconfig.json` file in the `server` folder with the basic TypeScript configuration:

  ```json
  {
    "compilerOptions": {
      "target": "ES2020",
      "module": "commonjs",
      "outDir": "dist",
      "rootDir": "src",
      "strict": true,
      "esModuleInterop": true,
      "skipLibCheck": true
    }
  }
  ```

## Implement the Verification Route

In the file `server/index.ts`, implement a route to verify the signature:

```typescript
import express, { Request, Response } from 'express';
import cors from 'cors';
import bodyParser from 'body-parser';
import { Client, PublicKey, Signature, cryptoUtils } from '@hiveio/dhive';

const app = express();
app.use(cors());
app.use(bodyParser.json());

const client = new Client(['https://api.hive.blog']);

app.post('/verify', async (req: Request, res: Response) => {
  const { username, message, signature: signatureStr } = req.body;

  try {
    const account = await client.database.getAccounts([username]);
    if (!account || account.length === 0) {
      return res.status(404).json({ error: 'User not found' });
    }

    const publicKeyData = account[0].posting.key_auths[0][0];
    const publicKeyStr = typeof publicKeyData === 'string' ? publicKeyData : publicKeyData.toString();

    const publicKey = PublicKey.fromString(publicKeyStr);
    const signature = Signature.fromString(signatureStr);

    const messageHash = cryptoUtils.sha256(message);

    const isValid = publicKey.verify(messageHash, signature);

    if (isValid) {
      res.status(200).json({ success: true, message: 'Valid signature' });
    } else {
      res.status(401).json({ success: false, message: 'Invalid signature' });
    }
  } catch (error) {
    console.error('Error verifying signature:', error);
    res.status(500).json({ error: 'Internal server error' });
  }
});

app.listen(6001, () => {
  console.log('Backend server running at http://localhost:6001');
});
```

## 🧪 Testing/Launching the Application

* Run:

  ```bash
  npx ts-node index.ts
  ```

## Pro-tip

Always start the backend first. You don't need to open multiple VSCode editors; simply open at least two terminals in the terminal section below. Navigate using the commands `ls` and `cd` to move to the `client` and `server` folders respectively.

> This way, you can run each part in a separate console.

---
</details>
👍  , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , and 134 others
properties (23)
authortheghost1980
permlinkhive-tutorials-auth-login-keychain-react-fullstack-or-englishspanish
categoryhive-186392
json_metadata"{"app":"peakd/2025.4.6","format":"markdown","description":"Hive Keychain Fullstack React Nodejs Auth Login | Proceso como fullstack para logueo usando Hive Keychain","tags":["hive-dev","hive","keychain","venezuela","archon","typescript","express","blockchain","tutorial","reactjs"],"users":["latest","types","hiveio"],"image":["https://files.peakd.com/file/peakd-hive/theghost1980/AK28WwbrnospvWyvzep8kA8j5ws9yiozkkEAk1zwED9t6BJ7PCoQxH54jWakVwa.jpg","https://files.peakd.com/file/peakd-hive/theghost1980/Eo2BpKHNqwzA6mTZQaxqSFZ5wVgqggNaichpFcfuDa6Siu9GRGTETMz1BcRzaGsfLdo.png","https://files.peakd.com/file/peakd-hive/theghost1980/23t74tV4g6vDzGEwkqjRrhS7UhLTZX2WjwHjs5ovLxs9kwoETsGcfTwc4yV9VzR6cYjMZ.png","https://files.peakd.com/file/peakd-hive/theghost1980/23rB9Ruc4tg55s7AorisQ32mc39K4XK8z4hbTDdVdkMjfv8Fk4jKzKjZ3g28jJe2iVPDR.png","https://files.peakd.com/file/peakd-hive/theghost1980/246GKuDiAoFF8QbW5dVTxrBCroUuuuceHczJYafFptk2ViPtjZmaeGLq29u5Aym5jHgrn.png","https://files.peakd.com/file/peakd-hive/theghost1980/244UoTZPXQHsmotSQpqb1DYDKUmw4tvuLtjqCnHaWtwHtNiFcSJtf5RHCg74QkbB7jbwo.png"]}"
created2025-05-05 13:07:57
last_update2025-05-05 13:07:57
depth0
children2
last_payout2025-05-12 13:07:57
cashout_time1969-12-31 23:59:59
total_payout_value6.287 HBD
curator_payout_value6.260 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length17,649
author_reputation101,447,694,550,284
root_title"Hive Tutorials Auth Login Keychain React Fullstack | english/spanish"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd0
post_id142,527,200
net_rshares34,486,131,733,169
author_curate_reward""
vote details (198)
@mengao ·
keychain already checked the signature when it returned a success message, why do you check again in the backend?

also, have you checked out AIOHA? you can do Hive authentication using keychain, hiveauth, hive signer, ledger and peak vault. all in one
properties (22)
authormengao
permlinkre-theghost1980-svt5u1
categoryhive-186392
json_metadata{"tags":["hive-186392"],"app":"peakd/2025.4.6","image":[],"users":[]}
created2025-05-05 21:46:51
last_update2025-05-05 21:46:51
depth1
children1
last_payout2025-05-12 21:46:51
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length252
author_reputation113,604,055,991,028
root_title"Hive Tutorials Auth Login Keychain React Fullstack | english/spanish"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id142,538,940
net_rshares0
@theghost1980 ·
Hi there @mengao thanks for leaving a reply. In deed there are many ways to do things when we talk about programming. Aihoa is an amazing project that uses all in one auth methods but, some will prefer to do things in their own way, like me for example. Hive is blessed by having different libraries so devs can use different methods. There may be some users who just want to do a simple login only using a library without dependencies and this is why they may be choosing [keychain-helper](https://www.npmjs.com/package/keychain-helper) instead of using Aihoa :)

About the "why you check again if Hive Keychain has already checked" question:
---
ES
## 🔑 Seguridad del Login con Hive Keychain y Backend 🛡️

### ¿Por qué verificar la firma en el Backend? ✅

* Keychain firma de forma segura, pero tu backend necesita **confirmar esa firma**.
* Es la **prueba criptográfica** 🔑 de que quien inicia sesión posee la clave privada del usuario de Hive.
* Previene **suplantación de identidad** 😈 y asegura que solo los usuarios legítimos accedan a tu app.

### Ataques en Transmisión (Keychain -> Backend) 🚨

La data (firma, usuario, mensaje) viaja y es vulnerable a:

* 🕵️‍♂️ **Interceptación:** Leer la data.
    * 🔒 **Mitigación:** **HTTPS** (cifra la conexión).
* ✏️ **Manipulación:** Alterar la data en tránsito.
    * ✅ **Mitigación:** La **verificación de firma falla** si la data es alterada.
* 🔁 **Replay:** Reutilizar una firma vieja.
    * ⏳ **Mitigación:** Incluir **challenges únicos/temporales** en el mensaje a firmar (el backend los valida).

---

ENG

## 🔑 Hive Keychain & Backend Login Security 🛡️

### Why Verify the Signature on the Backend? ✅

* Keychain securely signs, but your backend needs to **confirm that signature**.
* It's the **cryptographic proof** 🔑 that the login is from the actual owner of the Hive user's private key.
* Prevents **identity spoofing** 😈 and ensures only legitimate users access your app.

### Attacks in Transmission (Keychain -> Backend) 🚨

The data (signature, user, message) travels and is vulnerable to:

* 🕵️‍♂️ **Interception:** Reading the data.
    * 🔒 **Mitigation:** **HTTPS** (encrypts the connection).
* ✏️ **Tampering:** Altering the data in transit.
    * ✅ **Mitigation:** **Signature verification fails** if the data is altered.
* 🔁 **Replay:** Reusing an old signature.
    * ⏳ **Mitigation:** Include **unique/temporal challenges** in the message to be signed (backend validates them).
properties (22)
authortheghost1980
permlinkre-mengao-svu0ps
categoryhive-186392
json_metadata{"tags":["hive-186392"],"app":"peakd/2025.4.6","image":[],"users":["mengao"]}
created2025-05-06 08:54:03
last_update2025-05-06 08:54:03
depth2
children0
last_payout2025-05-13 08:54:03
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length2,452
author_reputation101,447,694,550,284
root_title"Hive Tutorials Auth Login Keychain React Fullstack | english/spanish"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id142,549,240
net_rshares0