Use scoped tokens to load <audio> urls instead of JWT
Part of #1108 (closed)
Rationale
We sometimes need to embed a token in the <audio src="">
URL, as we cannot override the Authorization
header there (the browser handles the request for us). As a workaround, we supported providing the jwt
param in the querysting, which worked great but wasn't really great in terms of security: if you share the download URL, or shared some browser logs in a chat, everyone could access your account.
This proposal mitigates this by:
- Allowing the generation of scoped tokens (tokens with a restricted set of capabilites) on server side
- Extend the JSON payload returned by
/api/v1/users/me
to include a new property,"tokens": {"listen": "<token>"}
- Using this token in the querystring instead of the JWT token
- Expiring scoped tokens after 3 days
The listen
token can only be used to access the /api/v1/listen
endpoint, meaning in the worst case scenario, if a token is leaked, someone will be able to listen to some tracks on behalf of you (assuming they also know the corresponding track and upload uuid) for a period of 3 days.
If a user changes their password (which triggers an update of user.secret_key
), all their existing tokens are invalidated.
In the UI, we call /users/me
every few hours to ensure we always have a valid token (and refresh the user profile, as well).
I plan to implement something similar for websockets, by adding a new oauth scope for websockets, and include a new token for this scope in the tokens
returned by /users/me
.
Note that this change is fully backward compatible (nothing was removed on the API regarding JWT).