I previously read that Access Token must be sent with every request to the API but Refresh Token must be sent ONLY when the Access Token expires.
I'm trying to use a similar model to the conventional model, where the Access Token is JWT, but the Refresh Token is just a random unique string (stored on server)
so the Access Token JWT claims looks like this:
{
"user_id": "user123456789",
"refresh_token": "A9t2G8eH8j2QW2j9U",
"exp": 154922000
}
When a client sends a request to my API, the Access Token (JWT) will be sent to the server. If it is expired, then a new Access Token will be sent to them with a newly-generated Refresh Token alongside the HTTP Response of the requested resource (after doing some validation).
This way:
The client only needs to securely-save and send one JWT Token instead of two, with their requests.
The client doesn't have to make a second request just to refresh their Access Token in case if it's expired. (No 401 HTTP Response).
Request with valid AccessToken => (Response with the requested resource)
Request with expired AccessToken => (Response with the requested resource + New AccessToken)
The problem here is that the Refresh Token (random unique string) is being sent with every request over the wire in plain text, and I can't want to force my clients to use HTTPS only.
but then again, even in the "conventional model" the Refresh Token will be sent every X period of time, and a packet sniffer will be able to steal it easily if the connection wasn't over HTTPS
Am I missing something here? Is my model flawed? Or is the conventional OAuth model must be strictly used over HTTPS? Is forcing HTTPS is my last resort?