I'm writing a dashboard for my Discord bot. The frontend is an SPA app that I made using SolidJS and the backend (used for calling my API, for fetching various user data) for the app is an express NodeJS server.
My current flow is this: issue the client code using the generated discord oauth authorization link (by clicking Login button in my app), send the received code from the browser app to my API (using /auth/login route), call the Discord API on the backend to receive the bearer access token, store the access token as it is in the cookie and use this token stored in the cookie to make calls from the frontend to backend with access token set as a Authorization header.
I need to send the token with every call, because I need to authenticate the user before processing any request using Discord API (like users/@me or users/@me/guilds), and then process the request if the authentication was successful.
The obvious issue with that is that I'm sending the actual Discord access token with every API call, that is not encrypted or anything. But I don't know how else I could store this token, to be able to send it with API calls to the backend.
My question is: what would be the proper approach of handling the token that is used that way? Is the approach of attaching the token to every call in the Authorization header even correct?
Is the approach of sending the authorization code to the backend that then receives the access token correct, or maybe the frontend should make a call for the access token itself (in that case, how it should be stored/protected)?
I think you can have a look at these options:
Since it is your backend that obtains the discord access token and subsequently sends API requests to discord, I think you can keep the access token in the backend. You can establish an HTTP session with your front end, then save the discord access token in a database together with the session ID. Then you can easily use that token when you get a request from your front end — the backend obtains the session ID from the session cookie, then reads the discord token from the DB and makes an API call to discord.
If you don't want to maintain a separate database, you can still keep your discord tokens in cookies, but make sure they are HTTP-only cookies and that you use a secure connection from your front end to the backend (use HTTPS). The cookie will be sent to your backend on every request, then the backend can take the token from the cookie and make a call to the discord API. This solution is pretty secure, as the cookie will be protected in transport (through the use of SSL) and from XSS attacks (as HTTP-only cookies cannot be read by scripts).