I am currently building an application that uses the Spotify API to work with a user's playlists. My frontend is a Flutter app, which is connected to the backend, that is built with Node.js. Currently my backend handles the logic of implementing the [Authorization Code flow1 by using the spotify-web-api-node package. I implemented the auth flow in my app as follows:
After setting up the SpotifyWebApi object (provided by the package) on the backend, my frontend makes a request to retrieve an authorization URL which is used to allow the user to login through Spotify in a WebView. After granting the app permission to access the user's data, Spotify redirects the WebView to a callback on the backend, which generates the access token and finally redirects the frontend to an URL with the token embedded as an query parameter (e.g.: res.redirect('../auth/callback?token=${token}')). Once the WebView in the frontend reaches the URL with the token, it is stored on the frontend for future requests and the WebView is closed. Thus the user has logged in successfully and the frontend can now make requests to the backend to access the playlist data, by adding the stored token in an authorization header.
Now I have a few questions regarding my implementation:
- Is it safe / a good practice to pass the access token to the frontend through a query parameter during a redirect after authorizing / logging in?
- Does it make sense to handle all auth logic on the backend or should some of it be handled by the frontend? I am asking this since i have seen a few examples provided by Flutter auth packages (e.g. flutter_appauth), which seem to indicate that the authorization process could also be handled in the frontend. However I would then need to store some of the secrets from the backend (like client_id and client_secret to authenticate the application with Spotify) in the frontend, which seems odd to me.
- Is there maybe another way to structure this auth flow in a secure way, which is different from the way I currently implemented it or from the way I mention in the second question?
access_token- is there any reason to generate a second token in your backend? If you want to handle Auth Code flow from a browser-based UI app then consider using PKCE to avoid the need for aclient_secret. (and indeed avoid any involvement in your backend anywhere in the process aside from calls into the provider's own API, since I assume the purpose of the token is to get the client's authorisation).access_tokenis generated through use of theSpotifyWebApiobject which happens in the backend. I just call the objects method which returns theaccess_token. I place the token in a JSON Web Token which is then embedded in the query parameter of the redirect as mentioned above. Would you say it is a good idea / best practice to avoid any involvement of the backend in the auth process and instead just let it handle the requests to the Spotify API?access_token(a JWT) should simply be returned in exchange for the Auth code. I'd recommend going back to the provider's documentation and looking into other OAuth2 docs.