You certainly can't trust the Origin header generally. You can trust the origin header when it is a request from a browser, but if malicious attackers are using your endpoint directly via a client they control, then the origin header is meaningless. So whether or not it helps depends on the circumstances.
Now obviously that authentication token is public - anyone viewing your client's page can see their token and steal it. Hence the emphasis on Public token. Different services address this issue in different ways, depending on what you are trying to secure. The most common solution is to have different private and public keys with different security rules or options associated with them. Let's consider two examples: a mapping service (i.e. google maps) and a credit card processor.
Regarding usage outside of a browser, there is really no motivation for someone to do that other than spite. Sure, someone could copy your public token and generate a script that makes API calls using it and pretending to be from a white-listed domain (because using a non-browser HTTP client lets you easily spoof the Origin header), but why? Since this mapping service just returns maps to display in the browser, there is no gain. The only reason to really do it is if you really don't like the business you stole the public auth key from, and want to run up a large bill on their service. Probably not the most common attack vector.
So in a case like this public authentication tokens and an origin check are more than sufficient for the use case.
Credit card processor
So what do you do? Separate out secure actions with a private authorization token, and only allow the public authentication token to request actions. Those actions must then be authorized via a separate API call from the client's server itself using a private key not shared with anyone. For Stripe it looks like this:
- Stripe sends back a single-use "transaction" token that is useless on its own
- E-commerce site sends additional API call directly to stripe with single use "transaction" token using a private authorization token, telling Stripe what to actually do with the corresponding credit card (aka bill it, refund it, etc...).
This is obviously a more complicated flow, but it is necessary to protect sensitive API calls because nothing in the browser is private and there is no way to guarantee that you are actually talking to a browser if you are looking from the perspective of an API service.