No Allow-Acces-Control-Origin Header on Convert Get Trade Endpoint

Just fyi the new Get Convert Trade endpoint doesn’t seem to have CORS enabled.

So when I send a request to it from my webapp hosted at localhost:3000, I get the error

Access to XMLHttpRequest at ‘https://api.coinbase.com/api/v3/brokerage/convert/trade/ccdca436-d803-4b64-a4a3-2bdbd4262db3’ from origin ‘http://localhost:3000’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

Thanks for checking it out!

With nodejs, the endpoint works just fine! Also I noticed in my browser request I was missing the required scopes “from_account”, “to_account.”
It’d be nice if we only needed to provide the trade_id to get a trade’s details. The current transactions endpoints don’t tell you the “to” account of conversions. If you are querying the “from_account” asset this is problematic.

For instance if a conversion happened from BTC → ETH
And I request this BTC transaction, it won’t specify to which account/asset the trade went to (ETH in this case)!

1 Like

This is actually by design and doesn’t really have anything to do with coinbase.

TL;DR: If the request comes from the browser/frontend, it won’t work. If the request comes from a server/backend (node.js in your case), you’re fine.

Basically, when you make a request from a browser, it sends a bunch of authentication stuff that has been stored in your browser so the server you are sending the request to knows who you are. It gets this stuff when you log in to the site.

This is a security risk. I could make a website called badwebsite.com. If you visit it, I could make a request from your browser to coinbase.com, and if you’re logged in to coinbase I could make some trades or do whatever I want since it would send your legitimate coinbase auth stuff with the request.

The solution: Your browser will ask the coinbase.com server what sites are allowed to make requests. Coinbase responds with a list. Your browser will check if the website making the request is on the list. Since badwebsite.com is not on the list, your browser refuses to make the request. This stops badwebsite.com from doing stuff on coinbase with your coinbase credentials.

It’s a concept that’s a little hard to grasp when you’re just developing on your own computer, because it feels like the request comes from the same computer either way, which is true. The difference is that when you send the request from node, it’s coming from the backend. Node doesn’t have any of the stuff that’s stored in the browser, and can’t get anything unless you give it to node manually, ie with a form for api keys or log in with coinbase or whatever.

The reason you see " from origin http://localhost:3000" is because that’s what your browser sees as the url for your website.

You’ll probably run into this again elsewhere in the future, and might see some tips on how to disable CORS in the browser. This is terrible advice, never disable CORS. Huge security risk.

One use for allowing a site through CORS is if you had a website, like goodwebsite.com, and you want to log some statistics for your users at another site, like userlogs.com. You might add goodwebsite.com to the CORS list on userlogs.com. Then when a user is doing something on goodwebsite.com, you can make an api call to userlogs.com to log some data, and the user’s browser will be okay with that because it sees goodwebsite.com on the CORS allow list. This is the meaning of CORS. Cross-Origin Resource Sharing. resources (userlogs) are being shared across two different origins (goodwebsite and userlogs).

Probably more info than you were looking for lol but I hope that clears it up for you.

1 Like

Thanks for the response. Yes, cors make sense, however i’m developing a webapp (which is why I’m sending requests from the browser) and am using methods like OAuth to securely allow requests from the client. Actually some of their endpoints seem to work from the browser (localhost in my case). Particularly I’ve tried /accounts which returned the user’s accounts and transactions. However it’s unfortunate that the response misses trade/conversion information (particularly which account the trade went to)! Which is why I tried the Get Trade endpoint for more details and ran into CORS. So I wonder why they have CORS enabled on some and not others. I just wrote this post as a result. As I believe getTrade is a new endpoint they just added. Perhaps they forgot or maybe as your answer implies it’s just on some endpoints and not others… Not sure why it would allow me to access all the other accounts, transactions, buys and sells from the web but not trades though.

I forgot to mention that some of the other endpoints like /accounts (and get transactions) have CORS enabled. And I’ve been able to send requests from my webapp to them (localhost:3k). So that’s why I’m confused as to why I haven’t been able to access the trades endpoint with the same method.

Yeah that is strange. A common practice is to allow localhost in CORS during development, but that would normally be turned off in production. Sometimes they will allow anything, but that’s not normally the case when authentication is needed.

But if you’re using OAuth, my understanding is that none of that matters. From the docs it looks like you might not be able to use new endpoints with it, so maybe the conversion stuff is still considered new (although it’s been 16 days lol), and you’ll be able to use it soon :man_shrugging: