Claves API de usuario: duplicar client_id provocará un error interno del servidor

Al llamar a user-api-key/new con un client_id que ya está en uso por otro usuario, el foro lanzará un error RecordNotUnique y fallará silenciosamente con un error interno del servidor.

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'

Esto podría querer fallar con algo menos silencioso, informando al usuario que ya existe una clave de API con ese ID de cliente.

Aunque eso me lleva a la segunda pregunta, ¿se supone que las claves de API de usuario deben comportarse así? ¿Se supone que el ID de cliente debe ser único entre todos los usuarios?

5 Me gusta

Un rápido empujón para visibilidad. Todavía vemos que estos aparecen con bastante frecuencia en nuestro endpoint /logs:

image

3 Me gusta

Gracias por informar de esto. Sin embargo, tengo un par de preguntas para poder investigar.

¿Puede proporcionar un ejemplo básico para poder depurar esto localmente? ¿Cuál es su caso de uso para las claves de API de usuario? ¿Está utilizando la aplicación móvil de Discourse Hub o algo más?

1 me gusta

No estoy seguro de lo que prefieres como reproducción, pero este fragmento de código PHP puede reproducirlo muy bien.

Código

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

// Obtener la clave pública
$public = openssl_pkey_get_details($keypair)["key"];

// Construir la consulta
$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 primera y repetida autorización tendrá éxito como el primer usuario, al usarla nuevamente para otro usuario sin cambiar el client_id fallará.
image

Las claves de API de usuario se utilizan para permitir que el usuario utilice su cuenta del foro en el cliente del juego, de modo que puedan publicar desde el juego. También tenemos muchos usuarios que las utilizan para autenticar sus cuentas del foro en sus propios sitios web.

Mientras que el client_id debe ser único para los clientes del juego, por lo que cada cliente se lista como un cliente separado en la pantalla de aplicaciones. Para el caso de uso del sitio web, querrás tener un client_id para que no cada inicio de sesión se liste por separado.

3 Me gusta

Me preguntaba si esto se resolvió.

¿Ha habido alguna actualización sobre esto? Todavía no está claro si el client_id debe ser globalmente único en lugar de por usuario.

1 me gusta

Debería ser globalmente único.

¿Cómo debería implementarse eso para casos de uso en los que un sitio web no tiene su propio sistema de autenticación para usuarios y no debería crear múltiples aplicaciones de API de usuario?

2 Me gusta

¿Establecer una cookie? O determinarla hashando algo que identifique al usuario (más algo “secreto” para que las partes externas no puedan replicarlo)

Si la aplicación que autentica a los usuarios debe usarse en varias computadoras y no tiene ningún dato de usuario previo a la autenticación, eso es imposible.

No entiendo cómo esto se relaciona con el OP, ya que describe un caso en el que un ID de cliente es compartido por varios usuarios, mientras que tu caso parece describir un escenario en el que un usuario tiene varios IDs de cliente.

Se llama ID de cliente y no ID de usuario porque un usuario puede tener varios clientes.

En la mayoría de los estándares como OAuth, el ID de cliente se describe como “identificador de aplicación” y se puede usar para todos los usuarios (no solo para uno), por ejemplo, los inicios de sesión sociales de tu foro siempre usan el mismo ID de cliente.

Sin embargo, dado que las claves API de usuario parecen estar diseñadas principalmente para clientes como las aplicaciones de Discourse, es posible que se hayan diseñado para ser únicas, sería bueno saber si lo son.

Responder a lo anterior dejaría claro si falta una verificación en user_api_keys.rb o si hay un índice incorrecto en la base de datos. Porque actualmente esas solicitudes arrojan un aterrador error 500 y aparecen en nuestro punto final /logs.

1 me gusta

¿Alguna novedad al respecto? Todavía vemos que los usuarios tienen problemas con esto.

1 me gusta

El error debería ser mejor, sí, pero client_id debe ser único.

Cuando envías usuarios de esa manera, debes generar un id único en tu llamada a la API. El índice es correcto, 1 usuario puede tener N client ids.