Chiavi API utente: client_id duplicato porterà a un errore interno del server

Quando si chiama user-api-key/new con un client_id già utilizzato da un altro utente, il forum restituirà un errore RecordNotUnique e fallirà silenziosamente con un errore interno del server.

ActiveRecord::RecordNotUnique (PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint \"index_user_api_keys_on_client_id\"
DETAIL:  Key (client_id)=(893e0230d52455ea9b729334) already exists.
)
(eval):105:in `exec_params'
app/controllers/user_api_keys_controller.rb:66:in `create'

Questo potrebbe voler fallire con qualcosa di meno silenzioso, informando l’utente che esiste già una chiave API con quell’ID client.

Anche se questo mi porta alla seconda domanda, le chiavi API utente dovrebbero comportarsi in quel modo? L’ID client dovrebbe essere univoco tra tutti gli utenti?

5 Mi Piace

Un rapido sollecito per visibilità. Stiamo ancora vedendo questi errori nel nostro endpoint /logs abbastanza frequentemente:

image

3 Mi Piace

Grazie per la segnalazione, ho un paio di domande per potermi occupare di questo problema.

Puoi fornire un esempio di base per questo in modo che possa eseguire il debug localmente? Qual è il tuo caso d’uso per le user-api-key? Stai utilizzando l’app mobile Discourse Hub o qualcos’altro?

1 Mi Piace

Non sono sicuro di cosa preferisci come riproduzione, ma questo frammento di codice PHP può riprodurlo benissimo.

Codice

// openssl genrsa -out keypair.pem 2048
$keypair = openssl_pkey_get_private(file_get_contents("keypair.pem"));

// Ottieni la chiave pubblica
$public = openssl_pkey_get_details($keypair)["key"];

// Costruisci la query
$query = http_build_query([
    "auth_redirect" => "https://localhost/redirect",
    "application_name" => "Test repro",
    "client_id" => "7624a5376b7f52eb403a",
    "scopes" => "session_info",
    "nonce" => bin2hex(random_bytes(16)),
    "public_key" => $public
]);

$url = "https://forum.cfx.re/user-api-key/new?" . $query;
header("Location: " . $url);

La prima e ripetuta autorizzazione avrà successo come primo utente, quando la si riutilizza per un altro utente senza cambiare il client_id fallirà.
image

Le chiavi API utente vengono utilizzate per consentire all’utente di utilizzare il proprio account del forum nel client di gioco, in modo che possano pubblicare dal gioco. Abbiamo anche molti utenti che le utilizzano per autenticare gli account del forum sui propri siti web.

Mentre l’ID client dovrebbe essere univoco per i client di gioco, in modo che ogni client sia elencato come client separato nella schermata delle app. Per il caso d’uso del sito web, vorresti avere un ID client in modo che non ogni accesso venga elencato separatamente.

3 Mi Piace

Mi stavo chiedendo se fosse stato risolto

Ci sono stati aggiornamenti in merito? È ancora poco chiaro se client_id debba essere univoco a livello globale anziché per utente.

1 Mi Piace

Dovrebbe essere univoco a livello globale.

Come dovrebbe essere implementato per i casi d’uso in cui un sito Web non dispone di un proprio sistema di autenticazione per gli utenti e non dovrebbe creare più applicazioni API utente?

2 Mi Piace

Impostare un cookie? O determinarlo tramite hashing di qualcosa che identifica l’utente (più qualcosa di “segreto” in modo che le parti esterne non possano replicarlo)

Se l’applicazione che autentica gli utenti deve essere utilizzata su più computer e non dispone di dati utente prima dell’autenticazione, ciò è impossibile.

Non capisco come questo si colleghi all’OP poiché descrive un caso in cui un ID client è condiviso da più utenti, mentre il tuo caso sembra descrivere un utente che ha più ID client.

Viene chiamato ID client e non ID utente perché un utente può avere più client!

Nella maggior parte degli standard come OAuth, l’ID client viene descritto come “identificatore dell’app” e può essere utilizzato per tutti gli utenti (non solo uno), ad esempio i tuoi accessi social del forum utilizzano sempre lo stesso ID client.

Tuttavia, poiché le chiavi API utente sembrano essere progettate principalmente per client come le app Discourse, potrebbero essere state progettate per essere univoche, sarebbe bello sapere se lo sono.

Rispondere a quanto sopra chiarirebbe se manca un controllo in user_api_keys.rb o un indice errato nel database. Perché attualmente queste richieste generano un preoccupante errore 500 e compaiono nel nostro endpoint /logs.

1 Mi Piace

Ci sono aggiornamenti in merito? Vediamo ancora utenti che riscontrano questo problema.

1 Mi Piace

L’errore dovrebbe essere migliore, sì, ma client_id deve essere univoco.

Quando invii gli utenti in quel modo, devi generare un ID univoco nella tua chiamata API. L’indice è corretto, 1 utente può avere N ID client.