SSO

Logowanie przez SSO (Single Sign-On)

SSO pozwala reklamodawcom logować się do panelu Adshero bezpośrednio z platformy sklepu — bez konieczności zakładania osobnego konta ani podawania dodatkowych danych logowania.

Przed użyciem SSO w Adshero musi już istnieć mapowanie sprzedawca/reklamodawca dla danego whitelabel. sellerId przekazywany do SSO to identyfikator sprzedawcy z feeda (g:external_seller_id albo ah:external_seller_id) i musi być przypisany do reklamodawcy typu SELLER w tym whitelabel. SSO nie tworzy mapowań sprzedawca/reklamodawca.

Token JWT

Token JWT musi być podpisany algorytmem HMAC-SHA256 (HS256) przy użyciu wspólnego sekretu. Sekret do podpisywania tokenów otrzymuje się od zespołu Adshero w postaci zakodowanej base64.

Przed podpisaniem tokenu należy zdekodować sekret z base64 i użyć zdekodowanych bajtów jako klucza HMAC dla HS256. Nie należy używać bajtów surowego stringa sekretu jako klucza.

Header:

{
  "alg": "HS256"
}

Payload — powinien zawierać następujące pola:

{
  "sub": "user@example.com",
  "iss": "string",
  "seller_ids": ["SELLER-001"],
  "exp": 1893456000
}

Opis pól tokenu:

  • sub — Adres e-mail użytkownika. Będzie to również login utworzonego w systemie Adshero użytkownika.
  • iss — Unikalny identyfikator whitelabel (UUID) nadany przez Adshero.
  • seller_ids — Lista identyfikatorów sprzedawców (external_seller_id z feeda), do których użytkownik ma dostęp. Musi zawierać wartość przekazywaną w parametrze zapytania sellerId; w przeciwnym razie logowanie zostanie odrzucone.
  • exp — Czas wygaśnięcia tokenu jako Unix timestamp w sekundach, nie w milisekundach. Token z przeterminowaną wartością exp zostanie odrzucony.
ℹ️
W panelu Adshero wyświetlamy imię i nazwisko zalogowanego użytkownika. Ponieważ token JWT nie zawiera tych danych, w procesie tworzenia użytkownika jako imię wstawiamy część adresu e-mail przed znakiem @. Nazwisko pozostaje puste.

Przykładowy generator URL SSO

Poniższy skrypt w Pythonie może służyć do testów albo jako referencja implementacyjna. Skrypt dekoduje sekret z base64, podpisuje token JWT algorytmem HS256, dodaje wybranego sprzedawcę do seller_ids, ustawia exp na godzinę od momentu uruchomienia i wypisuje gotowy URL logowania SSO.

#!/usr/bin/env python3
import base64
import hashlib
import hmac
import json
import sys
import time
import urllib.parse


iss, secret, seller = sys.argv[1:4]
sub = sys.argv[4] if len(sys.argv) > 4 else "test@adshero.io"


def b64(value):
    return base64.urlsafe_b64encode(value).rstrip(b"=").decode()


header = {"alg": "HS256", "typ": "JWT"}
payload = {"sub": sub, "iss": iss, "seller_ids": [seller], "exp": int(time.time()) + 3600}

unsigned = b64(json.dumps(header, separators=(",", ":")).encode())
unsigned += "." + b64(json.dumps(payload, separators=(",", ":")).encode())
sig = b64(hmac.new(base64.b64decode(secret), unsigned.encode(), hashlib.sha256).digest())
token = unsigned + "." + sig

print("https://api.adshero.io/v1/auth/sso?token=" + urllib.parse.quote(token) + "&sellerId=" + urllib.parse.quote(seller))

Użycie:

python3 sso.py '<iss>' '<base64-secret>' '<seller-id>' '<email>'

Opis argumentów:

  • iss - identyfikator whitelabel nadany przez Adshero.
  • base64-secret - sekret do podpisywania tokenów w postaci base64 otrzymany od Adshero.
  • seller-id - identyfikator sprzedawcy z feeda, który zostanie przekazany jako sellerId i zapisany w seller_ids.
  • email - adres e-mail użytkownika zapisany w polu sub.

Skrypt wypisuje kompletny URL w formacie:

https://api.adshero.io/v1/auth/sso?token=...&sellerId=...

Otworzenie wypisanego URL w przeglądarce rozpoczyna logowanie SSO dla wskazanego sprzedawcy.

Endpoint uwierzytelniania

Token JWT wygenerowany przez sklep zostaje wysłany do Adshero na endpoint:

GET https://api.adshero.io/v1/auth/sso?token={tokenJWT}&sellerId={sellerId} HTTP/2
curl --location --request GET \
    'https://api.adshero.io/v1/auth/sso?token={tokenJWT}&sellerId={sellerId}'

Opis parametrów zapytania:

  • token — Token JWT w standardowym formacie (header.payload.signature).
  • sellerId — ID aktualnie wybranego sprzedawcy (external_seller_id z feeda).

Zachowanie odpowiedzi:

  • Sukces — HTTP 302 z nagłówkiem Location ustawionym na wygenerowany magic-link logowania dla domeny frontendowej whitelabel.
  • Błąd — HTTP 302 z Location: /v1/auth/sso/error. Dotyczy to niepoprawnego tokenu, brakującego mapowania sprzedawca/reklamodawca, nieprawidłowego sprzedawcy (w tym braku sellerId w seller_ids), wygasłego tokenu albo błędnego podpisu. Endpoint nie zwraca odpowiedzi błędu w JSON.