I’ve seen multiple ways to do this during my stints during application assessments. One of the popular ways is the playing tennis way that you mentioned – sending the username and password in every request to authenticate the user. This, in my opinion, is unsafe, especially if the application isn’t single page. It is also not scalable, especially if you want to add authorization to your app in addition to authentication in the future (although I guess you could build something based on logins too)
Whichever you do end up using, ensure it is sent to you safely. HTTPS protects you across the wire, but it doesn’t protect you if you leak the session token via the URL (or worse, credentials via the URL). I would recommend using a header, or if that’s not feasible, sending the token via a POST request every time (this would mean a hidden form field on the user’s browser.) The latter approach of using a POST request should use CSRF defenses, just in case, though I suspect using the token itself might be some sort of a CSRF defense.
Last, but not the least, make sure you have some mechanism in the backend to purge expired tokens. This has been the bane of many applications in the past – a rapidly growing database of authentication tokens which never seems to go away. If you need to support multiple user logins, make sure you either limit the number, or have a shorter time limit on each token. As I said before, load testing may be the answer to this.
There are some other security concerns that I can think of, but they are too broad to be addressed at this stage – if you keep all the use (and abuse) cases in mind, you should probably be able to do a fairly good implementation of this system.