Store Auth-Token in Cookie or Header?
Cookie Based Authentication
Pros
HttpOnly Flag: Session cookies can be created with the HttpOnly flag which secures the cookies from malicious JavaScript (XSS-Cross-Site Scripting).
Secure flag: Session cookies can be created with Secure flag that prevents the cookies transmission over an unencrypted channel.
Cons
CSRF: Cookies are vulnerable/susceptible to CSRF attacks since the third party cookies are sent by default to the third-party domain that causes the exploitation of CSRF vulnerability.
Performance and Scalability: Cookie based authentication is a stateful authentication such that server has to store the cookies in a file/DB in order to maintain the state of all the users. As the user base increases the backend server has to maintain a separate system so as to store session cookies.
Token Based Authentication:
Pros
Performance and Scalability: Tokens contains the metadata and its signed value(for tamper protection). They are self-contained and hence there is no need of maintaining state at the server. This improves the performance and thus scalability when the expansion is required.
CSRF: Unlike cookie-based authentication, token-based authentication is not susceptible to Cross-Site Request Forgery since the tokens are not sent to third party web applications by default.
Cons
- XSS: Since the session tokens are stored in the local data storage of the browser and it is accessible to the JS of the same domain. Hence there is no option to secure session identifier from XSS attacks unlike HTTPOnly security flag which is available in the cookie-based authentication.
Conclusion
Both of the mechanisms have their own pros and cons as mentioned.In the present era of Application Development Frameworks, cons such as XSS and CSRF are taken care by the underlying framework itself and hence I feel it is without a doubt a clear trade-off on which developers and the stakeholders takes the decision.
The accepted answer is conflating session based authentication - where a session is maintained in backend database and is stateful with cookies, which are a transport mechanism and so the pros and cons are flawed.
As to whether an auth token should be stored in a cookie or a header, that depends on the client. If the client is another REST api, then passing it via the header makes sense.
If the client is a browser you could store the token in local/session storage and then send the token via the header (as the accepted answer says), but as you mentioned - this has vulnerabilities and is not recommended (see more on this here: https://auth0.com/docs/security/store-tokens).
If the client is an SPA you could just store the tokens in memory - which is probably the safest option, but then you will need retrieve new tokens between pages.
If you need persistence between pages, "the old fashioned way" may still be the best option - providing your cookies are http-only, secure, and you have implemented csrf protection (though soon this may not be necessary because of the same-site property). Providing you do implement csrf protection you will get all of the benefits of "cookie-less token based auth" and additional protection against XSS.