Referință tehnică

Documentație API – Autentificare

Pentru integrarea aplicațiilor partenere. Pentru teste interactive, folosiți API Playground. Gestionarea rolurilor (grupuri de permisiuni) și utilizatorilor per site este documentată la API gestionare site.

Introducere

SCMCGate – modul de autentificare centralizată pentru mai multe aplicații. Site-urile externe (parteneri) se autentifică prin API: trimit credențiale, primesc token, validează token-ul la fiecare request protejat.

Cum obține credențialele un partener (inclusiv non-tehnic)?

  1. Partenerul contactează administratorul SCMCGate (email, telefon).
  2. Administratorul adaugă site-ul în panou: Admin → Site-uri → Adaugă site (tip API).
  3. Sistemul generează client_id și client_secret.
  4. Administratorul transmite credențialele partenerului (email, etc.).
  5. Partenerul le transmite echipei tehnice pentru integrare.

Pentru partener atehnic: doar solicită accesul, primește credențialele și le transmite developerului. Documentația de integrare (/docs/api) este pentru echipa tehnică.

Autentificare: email + token

Login: utilizatorul introduce email + parolă. Backend-ul trimite la API și primește un token.

Request-uri ulterioare: se trimite token-ul în Authorization: Bearer <token>.

1. Verifică GET /api/auth/status – dacă enabled: false, blochează login
2. User introduce email + parolă
3. POST /api/auth/login (client_id, client_secret, email, password) → token
4. La fiecare request: Authorization: Bearer <token> + X-Client-ID
5. GET /api/auth/verify returnează user (id, name, email, roluri, atribuiri pe site)

Endpoint-uri

POST /api/auth/login

Request: {"client_id":"...","client_secret":"...","email":"...","password":"..."}

Response 200: {"token":"...","expires_in":3600,"site":{"id":1,"slug":"...","client_id":"..."},"token_bound_to_site_id":1,"user":{...},"request_id":"..."} — token-ul este legat strict de site.id / client_id. Fiecare răspuns API include request_id (și header X-Request-ID) pentru suport.

401: Credențiale invalide. 403: Autentificarea dezactivată.


GET /api/auth/verify

Headers: Authorization: Bearer <token>, X-Client-ID: <client_id>

Response 200: {"site":{...},"token_bound_to_site_id":1,"user":{...},"request_id":"..."}


GET /api/auth/status

Query: ?site=slug sau ?client_id=...

Response: {"enabled":true,"site_name":"...","flags":{"catalog_active":true,"auth_enabled":true}}. enabled este false dacă site-ul nu e activ în catalog sau autentificarea e oprită – în ambele cazuri nu permiteți login.

API gestionare site (roluri, companii, grupuri, utilizatori)

Partenerii cu site tip API pot gestiona datele proprii prin REST, sub prefixul /api/site/ (aceleași rute există și sub /api/v2/site/, comportament identic).

Autentificare (două moduri):

  • client_secret — header-e X-Client-ID și X-Client-Secret (ca la POST /api/auth/login). Acces complet la toate resursele site-ului. În POST/PATCH cu JSON puteți include și client_id / client_secret în corp.
  • Token utilizator (Bearer)Authorization: Bearer <token> (de la login) + X-Client-ID (fără secret). Permisiunile sunt reuniunea valorilor api_permissions de pe rolurile de site atribuite utilizatorului (configurate în panou la fiecare rol: ex. roles.read, users.write, companies.read, groups.read, sau * pentru tot). Fără permisiuni pe roluri, răspuns 403.

Condiție: site-ul trebuie să fie în producție (login API activ). În mentenanță sau retras, răspuns 403 – aceeași regulă ca la login.

Roluri — roles

CRUD REST (id numeric în URL). Răspunsul listă / detaliu include api_permissions (doar pentru configurare în panou).

Listă: query opționale q (nume/slug), sort (name, slug, created_at, updated_at), dir (asc / desc).

  • GET /api/site/roles — listă
  • POST /api/site/roles — body: {"name":"Nume rol","slug":"optional"} (slug generat din nume dacă lipsește)
  • GET|PATCH|DELETE /api/site/roles/{id}
Utilizatori — users
  • GET /api/site/users — paginare: per_page (implicit 50, max 100); filtre: q (nume/email), sort (name, email, created_at, updated_at), dir
  • POST /api/site/users — creează utilizator și îl leagă de site; body exemplu:
{
  "name": "Ion Popescu",
  "email": "ion@exemplu.ro",
  "password": "ParolaSigura1!",
  "password_confirmation": "ParolaSigura1!",
  "assignments": [
    { "site_role_id": 2, "is_primary": true, "metadata": {} }
  ]
}

assignments opțional; fiecare intrare atribuie un rol de site (definit în panou / GET /api/site/roles). site_role_id este ID-ul din acel site — nu se copiază între site-uri.

Același email pe mai multe site-uri: emailul este unic la nivel de cont (users). POST /api/site/users eșuează dacă emailul există deja. Pentru a da acces unui utilizator care există deja (creat de alt site sau din panou), folosiți:

  • POST /api/site/users/attach — body: {"email":"user@exemplu.ro","assignments":[{"site_role_id":2,"is_primary":true}]} (fără parolă). Leagă contul existent de site-ul curent și creează atribuirile de rol pe acest site. 422 dacă emailul nu există, dacă utilizatorul are deja acces la acest site sau dacă site_role_id nu aparține site-ului.
  • GET|PATCH|DELETE /api/site/users/{id} — la PATCH, assignments înlocuiește complet atribuirile pe acest site dacă este trimis. Răspunsul include site_companies și site_groups.
Companii — companies

Permisiuni API: companies.read / companies.write. Acțiunile de business pe companie (ca la roluri) sunt în action_keys în body la creare/actualizare.

  • GET /api/site/companies — listă
  • POST /api/site/companies — body: {"name":"Nume","slug":"optional","action_keys":["cheie_acțiune"]}
  • GET|PATCH|DELETE /api/site/companies/{id}
Grupuri — groups

Permisiuni API: groups.read / groups.write. La fel ca la companii: action_keys în body.

  • GET /api/site/groups — listă
  • POST /api/site/groups — body: {"name":"Nume","slug":"optional","action_keys":[]}
  • GET|PATCH|DELETE /api/site/groups/{id}
Legătură utilizator ↔ companie

Necesită users.write. Utilizatorul trebuie să fie deja pe site (înrolat).

  • POST /api/site/users/{id}/companies — body: {"site_company_id": 1} (adaugă utilizatorul în companie)
  • DELETE /api/site/users/{id}/companies/{company_id} — scoate utilizatorul din companie
Legătură utilizator ↔ grup
  • POST /api/site/users/{id}/groups — body: {"site_group_id": 1}
  • DELETE /api/site/users/{id}/groups/{group_id}

La login/verify, site_action_keys reunește acțiunile din roluri, plus acțiunile din toate companiile și toate grupurile la care utilizatorul este legat (reuniune).

Exemplu cURL (listă roluri, client_secret)
curl -s "https://autentificare.master-data.ro/api/site/roles" \
  -H "X-Client-ID: YOUR_CLIENT_ID" \
  -H "X-Client-Secret: YOUR_CLIENT_SECRET" \
  -H "Accept: application/json"
Exemplu cURL (același endpoint, Bearer)
curl -s "https://autentificare.master-data.ro/api/site/roles" \
  -H "X-Client-ID: YOUR_CLIENT_ID" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Accept: application/json"

Exemple

cURL Login:

curl -X POST https://autentificare.master-data.ro/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"client_id":"YOUR_ID","client_secret":"YOUR_SECRET","email":"user@domain.ro","password":"parola"}'

cURL Verify:

curl -X GET https://autentificare.master-data.ro/api/auth/verify \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "X-Client-ID: YOUR_CLIENT_ID"

Coduri eroare

200Succes
401Token invalid, credențiale greșite
403Acces interzis (site dezactivat, user fără acces)
422Date invalide — JSON: {"message":"...","errors":{"camp":["..."]},"request_id":"..."}; mesajele sunt în limba setată de API_LOCALE (implicit engleză pentru integratori).
500Eroare server

Securitate

  • Folosiți HTTPS întotdeauna.
  • client_secret – doar pe server, niciodată în frontend.
  • Token – păstrați în cookie HttpOnly sau session, nu în localStorage.
  • La reverse proxy (Nginx, Apache), nu logați headere Authorization, X-Client-Secret sau cookie-uri brute.

Dezactivare autentificare

Când administratorul dezactivează autentificarea pentru site-ul dvs., Login și Verify returnează 403. Niciun utilizator nu poate să se autentifice până când nu este repornită. Verificați GET /api/auth/status la fiecare încercare de login.

Versiune API

Endpoint-urile sunt disponibile și sub prefix /api/v2/auth/... (comportament identic cu /api/auth/...). Păstrați aceeași logică; v2 permite evoluții viitoare fără a întrerupe clienții vechi.

Răspunsul GET /api/auth/status include site_status și flags (catalog activ, login permis).

SSO Keycloak (panou web)

Pentru autentificare în panoul central cu Keycloak, folosiți fluxul SSO din pagina de login. API-ul partenerilor rămâne pe /api/auth/*.

Arhitectură (rezumat)

Browser → SCMCGate (Laravel) → API partener
                    Keycloak → SCMCGate (SSO panou)
                    Partener → SCMCGate API → verificare token

Variabile .env (go-live)

  • APP_URL, APP_KEY, APP_ENV=production
  • Conexiune DB principală, SESSION_DRIVER
  • Keycloak: KEYCLOAK_* dacă folosiți SSO
  • METRICS_BEARER_TOKEN pentru /internal/metrics/prometheus
  • Cron: * * * * * php artisan schedule:run

CDN și asset-uri

Bootstrap și Font Awesome sunt încărcate de pe CDN în layout; pentru producție puteți trece la build local (Vite) și cache la edge.