# User API keys: duplicate client\_id will lead to internal server error

**URL:** https://meta.discourse.org/t/user-api-keys-duplicate-client-id-will-lead-to-internal-server-error/260995
**Category:** Bug
**Tags:** rest-api
**Created:** [April 7, 2023, 11:16pm UTC](https://meta.discourse.org/t/user-api-keys-duplicate-client-id-will-lead-to-internal-server-error/260995 "2023-04-07T23:16:23Z")
**Posts on this page:** 14
**Page:** 1

<div class="post-metadata">

### Author: ![Indra](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/indra/32/215866_2.png) [@Indra](https://meta.discourse.org/u/Indra)
#### Post date: [April 7, 2023, 11:16pm UTC](https://meta.discourse.org/t/user-api-keys-duplicate-client-id-will-lead-to-internal-server-error/260995/1 "2023-04-07T23:16:23Z")

</div>

When calling `user-api-key/new` with a `client_id` that is already used by another user the forum will throw a `RecordNotUnique` error and silently fail on an internal server error.

 ![image](https://global.discourse-cdn.com/meta/original/4X/4/0/8/408993b0ffe9ff13cba1af7235b4a5a0d368dc62.png)

```plaintext
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'

```

This might want to fail with something less silent informing the user that there already exists an API key with that client ID.

Though that brings me on the second question, are User API keys supposed to behave like that? Is the client ID supposed to be unique between all users?

---

<div class="post-metadata">

### Author: ![blattersturm](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/blattersturm/32/76134_2.png) [@blattersturm](https://meta.discourse.org/u/blattersturm)
#### Post date: [June 7, 2023, 7:06pm UTC](https://meta.discourse.org/t/user-api-keys-duplicate-client-id-will-lead-to-internal-server-error/260995/2 "2023-06-07T19:06:34Z")

</div>

> [@Indra](#):
>
> When calling `user-api-key/new` with a `client_id` that is already used by another user the forum will throw a `RecordNotUnique` error and silently fail on an internal server error.

Quick nudge for visibility. We’re still seeing these show up in our `/logs` endpoint fairly frequently:

![image](https://global.discourse-cdn.com/meta/original/4X/f/d/5/fd56b550ab7bd95c72591d178936cd1d65f4d281.png)

---

<div class="post-metadata">

### Author: ![blake](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/blake/32/157322_2.png) [@blake](https://meta.discourse.org/u/blake)
#### Post date: [September 13, 2023, 3:37pm UTC](https://meta.discourse.org/t/user-api-keys-duplicate-client-id-will-lead-to-internal-server-error/260995/7 "2023-09-13T15:37:37Z")

</div>

Thank you for reporting this, I have a couple of questions though in order to help me look into this.

> [@Indra](#):
>
> When calling `user-api-key/new` with a `client_id` that is already used by another user

Can you provide a basic repro for this so that I can debug this locally? What is your use case for user-api-keys? Are you using the discourse hub mobile app or something else?

---

<div class="post-metadata">

### Author: ![Indra](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/indra/32/215866_2.png) [@Indra](https://meta.discourse.org/u/Indra)
#### Post date: [September 16, 2023, 12:54pm UTC](https://meta.discourse.org/t/user-api-keys-duplicate-client-id-will-lead-to-internal-server-error/260995/8 "2023-09-16T12:54:01Z")

</div>

> [@blake](#):
>
> Can you provide a basic repro for this so that I can debug this locally?

I’m not sure what you prefer as repro, but this bit of PHP code can repro it great.

> **Code**
>
> ```php
> <?php
> 
> // openssl genrsa -out keypair.pem 2048
> $keypair = openssl_pkey_get_private(file_get_contents("keypair.pem"));
> 
> // Obtain the public key
> $public = openssl_pkey_get_details($keypair)["key"];
> 
> // Build the 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);
> 
> ```

The first and repeating authorization will succeed as the first user, when using it again for another user without changing the client\_id it will fail.  
 ![image](https://global.discourse-cdn.com/meta/original/4X/5/a/6/5a6e13b09fe2683b0f816fd11bcc3a2e2b693778.png)

> [@blake](#):
>
> What is your use case for user-api-keys? Are you using the discourse hub mobile app or something else?

User API keys are used for allowing the user to use their forum account in the game client, so they’ll be able to post from ingame. We also have lot of users using them to authenticate with forum accounts to their own websites.

Whereas the client ID should be unique for the game clients, so each client is listed as seperate client in the apps screen. For website usecase you’d want to have one client ID so not each login is listed separately.

---

<div class="post-metadata">

### Author: ![noornahas](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/noornahas/32/363360_2.png) [@noornahas](https://meta.discourse.org/u/noornahas)
#### Post date: [February 15, 2024, 1:17am UTC](https://meta.discourse.org/t/user-api-keys-duplicate-client-id-will-lead-to-internal-server-error/260995/9 "2024-02-15T01:17:53Z")

</div>

Was wondering if this was resolved

---

<div class="post-metadata">

### Author: ![Indra](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/indra/32/215866_2.png) [@Indra](https://meta.discourse.org/u/Indra)
#### Post date: [May 18, 2024, 7:39pm UTC](https://meta.discourse.org/t/user-api-keys-duplicate-client-id-will-lead-to-internal-server-error/260995/10 "2024-05-18T19:39:41Z")

</div>

Has there been any update about this? It’s still unclear whether the `client_id` should be globally unique instead of per-user.

---

<div class="post-metadata">

### Author: ![michaeld](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/michaeld/32/1594_2.png) [@michaeld](https://meta.discourse.org/u/michaeld)
#### Post date: [May 18, 2024, 8:16pm UTC](https://meta.discourse.org/t/user-api-keys-duplicate-client-id-will-lead-to-internal-server-error/260995/11 "2024-05-18T20:16:37Z")

</div>

It should be globally unique.

---

<div class="post-metadata">

### Author: ![hello-smile6](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/hello-smile6/32/304628_2.png) [@hello-smile6](https://meta.discourse.org/u/hello-smile6)
#### Post date: [May 18, 2024, 8:42pm UTC](https://meta.discourse.org/t/user-api-keys-duplicate-client-id-will-lead-to-internal-server-error/260995/12 "2024-05-18T20:42:34Z")

</div>

How should that be implemented for use cases where a website doesn’t have its own authentication system for users and shouldn’t be creating multiple user API applications?

---

<div class="post-metadata">

### Author: ![michaeld](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/michaeld/32/1594_2.png) [@michaeld](https://meta.discourse.org/u/michaeld)
#### Post date: [May 18, 2024, 9:01pm UTC](https://meta.discourse.org/t/user-api-keys-duplicate-client-id-will-lead-to-internal-server-error/260995/13 "2024-05-18T21:01:56Z")

</div>

Set a cookie? Or determine it by hashing something that identifies the user (plus something “secret” so external parties cannot replicate it)

---

<div class="post-metadata">

### Author: ![hello-smile6](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/hello-smile6/32/304628_2.png) [@hello-smile6](https://meta.discourse.org/u/hello-smile6)
#### Post date: [May 18, 2024, 9:02pm UTC](https://meta.discourse.org/t/user-api-keys-duplicate-client-id-will-lead-to-internal-server-error/260995/14 "2024-05-18T21:02:56Z")

</div>

> [@michaeld](#):
>
> Or determine it by hashing something that identifies the user (plus something “secret” so external parties cannot replicate it)

If the application authenticating users should be used on multiple computers and does not have any user data prior to authentication, that is impossible.

---

<div class="post-metadata">

### Author: ![michaeld](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/michaeld/32/1594_2.png) [@michaeld](https://meta.discourse.org/u/michaeld)
#### Post date: [May 18, 2024, 9:05pm UTC](https://meta.discourse.org/t/user-api-keys-duplicate-client-id-will-lead-to-internal-server-error/260995/15 "2024-05-18T21:05:58Z")

</div>

I dont understand how this relates to the OP since that describes a case where a client ID is shared by multiple users where your case seems to describe where a user has multiple client ids.

It’s called a client id and not user id because a user can have multiple clients!

---

<div class="post-metadata">

### Author: ![Indra](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/indra/32/215866_2.png) [@Indra](https://meta.discourse.org/u/Indra)
#### Post date: [May 18, 2024, 9:43pm UTC](https://meta.discourse.org/t/user-api-keys-duplicate-client-id-will-lead-to-internal-server-error/260995/16 "2024-05-18T21:43:24Z")

</div>

In most standards like OAuth the client id is described as “app identifier” and can be used for all users (not just one), for example your forum social logins always use the same client id.

However since user API keys seem to be designed primarily for clients such as Discourse apps they might have been designed to be unique, it would be nice to know whether they are.

Answering the above would make it clear whether there’s a check missing in `user_api_keys.rb` or a wrong index on the database. Because currently those requests currently throw a scary 500 error and show up in our `/logs` endpoint.

---

<div class="post-metadata">

### Author: ![Indra](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/indra/32/215866_2.png) [@Indra](https://meta.discourse.org/u/Indra)
#### Post date: [September 5, 2024, 1:17pm UTC](https://meta.discourse.org/t/user-api-keys-duplicate-client-id-will-lead-to-internal-server-error/260995/17 "2024-09-05T13:17:12Z")

</div>

Any update on this? We still see users running into this.

---

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [September 6, 2024, 6:37am UTC](https://meta.discourse.org/t/user-api-keys-duplicate-client-id-will-lead-to-internal-server-error/260995/18 "2024-09-06T06:37:04Z")

</div>

The error should be better, yes, but client\_id needs to be unique.

> <https://github.com/discourse/discourse/blob/ed7ba4b2a749ad26129e4fd848f39a0c4defed33/app/controllers/user_api_keys_controller.rb#L67-L74>

When you are sending users that way you must generate a unique id in your API call. The index is correct, 1 user may have N client ids.
