Note: The following description is out-of-date due to changes made to address PR comments. I am leaving it as-is for posterity (or laziness) but the comments paint the picture.
Motivation
Sometimes an existing API spec dictates that header- and token-based authentication is not associated with the "Authorization" key much less the Bearer strategy. I'm not prepared to argue the frequency with which this occurs, but I am currently working with an API that dictates the session token be passed as the value of a "Session-Token" header. My hope is that a low-overhead abstraction makes it easy to continue using Bearer Authentication while also making it easy to specify another header to look to for token-based authentication.
Strategy
Move most of what it means to be "bearer" based authentication into parent protocols and types.
Require the token used for authentication be exposed via a new static func authorization(from headers: HTTPHeaders) -> AuthorizationType?.
Make the bearer authentication protocols and types a thin layer over the above that specifies defaults including an implementation of authorization(from headers: HTTPHeaders).
Breaking Changes
Although I intentionally chose low-impact changes over reworking more than the minimum, I introduced a breaking change. Perhaps it is worth trying harder to avoid that, I am curious what the community's thoughts are. One option would be to leave TokenAuthenticatable coupled to BearerAuthenticatable and introduce a new type (CustomTokenAuthenticatable for lack of a better name at the moment) that is agnostic about the AuthorizationType. In reality, if this approach is pursued it would probably be cleanest to just typealias TokenAuthenticatable to CustomTokenAuthenticatable<BearerAuthenticatable>.
The only source-breaking change given the current PR is that existing implementations of TokenAuthenticatable'sToken protocol will need to additionally specify either a free conformance to BearerAuthenticatable or a typealias of AuthorizationType = BearerAuthorization. You can see this play out in the tests I began to add.
Documentation
If these changes are adopted I will gladly update the Vapor documentation to describe the new generalized capability and how to use the more common Bearer-based option.
Note: The following description is out-of-date due to changes made to address PR comments. I am leaving it as-is for posterity (or laziness) but the comments paint the picture.
Motivation
Sometimes an existing API spec dictates that header- and token-based authentication is not associated with the
"Authorization"
key much less theBearer
strategy. I'm not prepared to argue the frequency with which this occurs, but I am currently working with an API that dictates the session token be passed as the value of a"Session-Token"
header. My hope is that a low-overhead abstraction makes it easy to continue using Bearer Authentication while also making it easy to specify another header to look to for token-based authentication.Strategy
static func authorization(from headers: HTTPHeaders) -> AuthorizationType?
.authorization(from headers: HTTPHeaders)
.Breaking Changes
Although I intentionally chose low-impact changes over reworking more than the minimum, I introduced a breaking change. Perhaps it is worth trying harder to avoid that, I am curious what the community's thoughts are. One option would be to leave
TokenAuthenticatable
coupled toBearerAuthenticatable
and introduce a new type (CustomTokenAuthenticatable
for lack of a better name at the moment) that is agnostic about theAuthorizationType
. In reality, if this approach is pursued it would probably be cleanest to just typealiasTokenAuthenticatable
toCustomTokenAuthenticatable<BearerAuthenticatable>
.The only source-breaking change given the current PR is that existing implementations of
TokenAuthenticatable's
Token
protocol will need to additionally specify either a free conformance toBearerAuthenticatable
or a typealias ofAuthorizationType = BearerAuthorization
. You can see this play out in the tests I began to add.Documentation
If these changes are adopted I will gladly update the Vapor documentation to describe the new generalized capability and how to use the more common Bearer-based option.