omnium
A set of extensions for building web applications on axum.
Unstable: This crate is not ready for use. The author is building out these extensions to iterate on a proof of concept, and the surface may change frequently.
api
The api::responses module provides a set of response conventions for axum handlers, implementing axum's IntoResponse trait for typical use cases.
A handler returns JsonResult or TypedJsonResult<T>, where JsonResult can be used for type-erased responses and TypedJsonResult<T> can be used for consistently-typed responses.
The Ok(...) arm on these types can be used regardless of status code, to return custom responses:
// ...
use ;
async
Response conventions are provided through the JsonResponse<T> struct, which implements Into<JsonResult> and Into<TypedJsonResult<T>>, as well as axum's IntoResponse.
A handler can return a JSON response for any serializable body, with a default OK status:
async
Another status code can be set on the response:
async
A handler can return a simple JsonStatusBody status response, implicitly deriving the response body as appropriate for the status:
async
An additional detail message can be added to the JsonStatusBody:
async
The default JsonResult erases the response payload type. If you are returning a consistent type on response, you can return a TypedJsonResult<T>:
async
The Err arm is available on both JsonResult and TypedJsonResult<T> to handle status responses. For example, when using TypedJsonResult<T> for the happy path, you may choose to return status responses to communicate other results to the caller, whether for an error, informational result, or other case:
async
Finally, the Err arm is used to automatically handle internal server errors. A handler can return Err(Into<anyhow::Error>), which will be rendered as an INTERNAL_SERVER_ERROR response.
async
With this convention, unhandled errors have built-in IntoResponse rendering and other errors must be rendered explicitly by a handler. When the handler returns an internal error in this way, the error details are not visible to the caller.
security
The security module provides JWT-based authentication middleware, with utilities for a cookie-based credential exchange or the authorization header for browser-based or programmatic authentication.
Create a service secret:
let service_secret = create_service_secret;
Configure authentication middleware:
Attach authentication middleware:
Create the user session:
create_session;
With Credential::from_authorization_header, a client may pass the session as the authorization header. With Credential::from_cookie, a client may pass the session as the __Host-omn-sess cookie. For a simple, user-facing web application, you can set the __Host-omn-sess cookie when the user signs in, in order to authenticate requests to the service running on the same origin. If the application shares a session across multiple services on different origins, it can expose the session for use by the client in the authorization header for programmatic, cross-origin requests. You can plug in your own handling for extracting credentials from requests with a custom extract_credential handler.
Requests from an unauthenticated user will reject with a 401 response.
For an authenticated user, the user object from user_lookup can be retrieved from request state to avoid redundant lookup in handlers:
pub async
Because a variety of data may need to be passed and verified between an application and its users, encode_claims and decode_claims may also be used for other purposes other than authentication. Note that claims are signed but not encrypted.
In addition to claims-based utilities, this crate wraps aes_gcm to provide utilties encrypt_string_aes256_gcm and decrypt_string_aes256_gcm. A secret created by create_service_secret can also be used with these encryption utilities.