server: update refresh tokens instead of deleting and creating another

The server implements a strategy called "Refresh Token Rotation" to
ensure refresh tokens can only be claimed once.

ref: https://tools.ietf.org/html/rfc6819#section-5.2.2.3

Previously "refresh_token" values in token responses where just the
ID of the internal refresh object. To implement rotation, when a
client redeemed a refresh token, the object would be deleted, a new
one created, and the new ID returned as the new "refresh_token".

However, this means there was no consistent ID for refresh tokens
internally, making things like foreign keys very hard to implement.
This is problematic for revocation features like showing all the
refresh tokens a user or client has out.

This PR updates the "refresh_token" to be an encoded protobuf
message, which holds the internal ID and a nonce. When a refresh
token is used, the nonce is updated to prevent reuse, but the ID
remains the same. Additionally it adds the timestamp of each
token's last use.
This commit is contained in:
Eric Chiang
2016-12-22 16:41:30 -08:00
parent 312ca7491e
commit f778b2d33b
5 changed files with 134 additions and 38 deletions

25
server/internal/codec.go Normal file
View File

@@ -0,0 +1,25 @@
package internal
import (
"encoding/base64"
"github.com/golang/protobuf/proto"
)
// Marshal converts a protobuf message to a URL legal string.
func Marshal(message proto.Message) (string, error) {
data, err := proto.Marshal(message)
if err != nil {
return "", err
}
return base64.RawURLEncoding.EncodeToString(data), nil
}
// Unmarshal decodes a protobuf message.
func Unmarshal(s string, message proto.Message) error {
data, err := base64.RawURLEncoding.DecodeString(s)
if err != nil {
return err
}
return proto.Unmarshal(data, message)
}