# Naudotojų atpažinimas pokalbių valdiklyje

> Atpažinkite prisijungusius naudotojus: atpažinimo raktas, userHash skaičiavimas Node.js, PHP ir Python, el. pašto patvirtinimas ir atsijungimas.

Jei jūsų svetainėje ar programėlėje naudotojai prisijungia, valdiklis gali juos atpažinti. Tada žmogus mato savo pokalbius bet kuriame įrenginyje, o komanda mato vieną kontaktą, ne kelis anoniminius.

## Kodėl reikia parašo

Naršyklei negalima tikėti: bet kas gali parašyti `identify` su svetimu el. paštu. Todėl jūsų serveris apskaičiuoja `userHash`, HMAC-SHA256 parašą su atpažinimo raktu, kurio naršyklė niekada nemato.

## Atpažinimo raktas

Raktą rasite pokalbių valdiklio nustatymuose, skiltyje Naudotojų atpažinimas. Jį mato ir keičia tik savininkai.

- Laikykite raktą tik serveryje, pavyzdžiui kintamajame `SUPPORT_IDENTITY_SECRET`. Niekada nedėkite jo į naršyklės kodą.
- Sukūrus naują raktą, senas veikia dar 24 valandas, kad spėtumėte atnaujinti serverį.

![Naudotojų atpažinimo nustatymai su paslėptu raktu](https://hrc.lt/screens/lt/project-identity.desktop.1600.a3d340c9.webp)

## Ką pasirašyti

Parašas skaičiuojamas iš eilutės `v1:<ID>:<el. paštas>`. El. paštas be tarpų kraštuose ir mažosiomis raidėmis; trūkstama dalis lieka tuščia.

```text
v1:<externalId>:<el. paštas be tarpų kraštuose, mažosiomis>

v1:12345:jonas@example.com   ID ir el. paštas
v1:12345:                    tik ID
v1::jonas@example.com        tik el. paštas, reikia nustatymo
                             „Mano programa tikrina el. pašto adresus“
```

`userHash` yra šios eilutės HMAC-SHA256 su atpažinimo raktu, užrašytas 64 šešioliktainiais simboliais.

## Kodas serveriui

Node.js:

```js
// Node.js (Express): jūsų maršrutas, tik prisijungusiam naudotojui
import { createHmac } from 'node:crypto';

app.get('/api/support-hash', requireLogin, (req, res) => {
  const user = req.user;
  const email = (user.email ?? '').trim().toLowerCase();
  const canonical = `v1:${user.id ?? ''}:${email}`;
  const userHash = createHmac('sha256', process.env.SUPPORT_IDENTITY_SECRET)
    .update(canonical)
    .digest('hex');
  res.json({ userHash });
});
```

PHP:

```php
<?php
// PHP: mb_strtolower, ne strtolower, kad Ū ir Ž taptų mažosiomis
$email = mb_strtolower(trim($user->email ?? ''), 'UTF-8');
$canonical = 'v1:' . ($user->id ?? '') . ':' . $email;
$secret = getenv('SUPPORT_IDENTITY_SECRET');
$userHash = hash_hmac('sha256', $canonical, $secret);
```

Python:

```python
# Python
import hashlib
import hmac
import os

user_id = "" if user.id is None else str(user.id)
email = (user.email or "").strip().lower()
canonical = f"v1:{user_id}:{email}"
secret = os.environ["SUPPORT_IDENTITY_SECRET"].encode()
user_hash = hmac.new(secret, canonical.encode(), hashlib.sha256).hexdigest()
```

## Kodas naršyklei

`externalId` visada perduokite kaip tekstą: skaičius ignoruojamas.

```js
// Naršyklėje: paprašykite savo serverio prisijungusio naudotojo parašo
const { userHash } = await fetch('/api/support-hash', {
  credentials: 'include',
}).then((r) => r.json());
HrcWidget('identify', {
  externalId: String(user.id ?? ''),
  email: user.email,
  name: user.name,
  userHash,
});

// Atsijungus
HrcWidget('reset');
```

Su `identify` galite perduoti ir profilio laukus, žr. [Lankytojo profilis](https://hrc.lt/dokumentacija/valdiklis/lankytojo-profilis).

## „Mano programa tikrina el. pašto adresus“

Įjunkite tik tada, jei jūsų programa patikrina, kad el. paštas priklauso naudotojui (atsiunčia kodą ar nuorodą). Tada pasirašytas el. paštas sujungia to paties žmogaus laiškus ir pokalbius į vieną kontaktą visuose valdikliuose ir pašto dėžutėse.

Kol šis nustatymas išjungtas, visada perduokite naudotojo `externalId`. Pasirašytas el. paštas be ID atmetamas su klaida `IDENTITY_INVALID`, o el. paštas laikomas nepatvirtintu, kol žmogus neatsako į mūsų laišką.

## Tik prisijungusiems

Režimas „Tik prisijungusiems“ leidžia rašyti tik atpažintiems naudotojams. Neatpažinta sesija negali siųsti žinučių ir keisti profilio (`IDENTITY_REQUIRED`).

## Patikrinkite parašą

Nustatymuose yra laukas „Patikrinti apskaičiuotą reikšmę“: įveskite ID, el. paštą ir savo serverio apskaičiuotą reikšmę, ir programa pasakys, ar ji tinka. Patikra vyksta serveryje, raktas į naršyklę nesiunčiamas. Jei netinka, patikrinkite, ar el. paštas mažosiomis raidėmis ir ar naudojate šio valdiklio raktą.

Klaidą matote ir savo svetainėje: `HrcWidget('on', 'identify-failed', ...)` gauna kodą, niekada ne patį parašą.

## Atsijungimas

Kai naudotojas atsijungia, iškvieskite `HrcWidget('reset')`. Valdiklis pamirš sesiją, ir kitas žmogus tame pačiame įrenginyje nematys svetimų pokalbių.
