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)?
- Partenerul contactează administratorul SCMCGate (email, telefon).
- Administratorul adaugă site-ul în panou: Admin → Site-uri → Adaugă site (tip API).
- Sistemul generează
client_idșiclient_secret. - Administratorul transmite credențialele partenerului (email, etc.).
- 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șiX-Client-Secret(ca laPOST /api/auth/login). Acces complet la toate resursele site-ului. ÎnPOST/PATCHcu JSON puteți include șiclient_id/client_secretîn corp. - Token utilizator (Bearer) —
Authorization: Bearer <token>(de la login) +X-Client-ID(fără secret). Permisiunile sunt reuniunea valorilorapi_permissionsde 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"}(sluggenerat 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),dirPOST /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_idnu aparține site-ului.
GET|PATCH|DELETE /api/site/users/{id}— laPATCH,assignmentsînlocuiește complet atribuirile pe acest site dacă este trimis. Răspunsul includesite_companiesșisite_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
| 200 | Succes |
| 401 | Token invalid, credențiale greșite |
| 403 | Acces interzis (site dezactivat, user fără acces) |
| 422 | Date invalide — JSON: {"message":"...","errors":{"camp":["..."]},"request_id":"..."}; mesajele sunt în limba setată de API_LOCALE (implicit engleză pentru integratori). |
| 500 | Eroare 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-Secretsau 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_TOKENpentru/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.