Outgoing Request Authorization
Ultimately the goal of performing client authentication is to send network requests authorized as some user. The process by which these requests are authorized, and which attributes or headers are used for a variety of different credentials, can vary between users or environments.
Typical applications simply attach an access token to an outgoing request's Authorization HTTP header, but this doesn't tend to scale well. Not only does this complicate an application's logic since requests are often sent from a variety of locations throught a codebase, but these tokens may expire which necessitates them being refreshed. As a result, app developers often refresh their tokens unnecessarily which can slow down every user operation.
This is further complicated when modern security features are used (such as DPoP) which goes beyond simple additions to an HTTP header.
Ultimately developers shouldn't need to know how a request is authorized and which steps need to be performed to ensure this authorization is valid. The SDK should free developers from needing to worry about these implementation details.
HTTP Request Authorization
Given the protocol-oriented design of the SDK, and the goal to support a variety of developer use-cases flexibly and extensibly, this SDK breaks the request authorization process into a separate set of interfaces and classes to simplify these components, and to enable simpler unit testing.
Token / API Authorization
In order to decouple the understanding of what authorization the client has available, and what specific workflows or implementation details are neccessary to supply that authorization to a server request, an interface abstraction is used to separate specific details like an Access Token from the resource a developer is using.
For example, the Token class conforms to APIAuthorization to indicate that it can be used to authorize server requests.
Following an interface-oriented approach can enable use-cases where non-OAuth2 credentials, such as API keys or SAML tokens can be used to authorize network requests.
This effectively decouples the concrete implementation of Token from the API client, allowing it to be separated from the primary codebase.
API Client Authorization interface
The OAuth2Client is just one type of API client, but not all developers will want to use a client instance for all network operations their application performs. They may want to separate the SDK's authentication handling from the rest of their network interactions.
To ensure compatibility with other unknown systems, the ability to authorize an outgoing request with a user's access tokens should be defined as an interface that a developer can plug into.
HTTP Request Authorization
Given the protocol-oriented design of the SDK, the APIAuthorization protocol is used to define how the necessary HTTP headers are generated for a given request.
The Token class implements APIAuthorization, which allows it to return the headers for its access token authorization header, and to also generate the appropriate DPoP tokens for outgoing requests (when DPoP is enabled).
The Credential class contains a convenience function named authorize(_:) which uses refreshIfNeeded to ensure the token is refreshed and up to date prior to performing a request, and then attaches the headers resulting from the APIAuthorization protocol bound to the Token to decorate a request with its headers.
This effectively allows a developer to send requests to a resource server without having to worry about token validity, authorization, or expiration.