# HMAC Authentication Plug
[Plug](https://hex.pm/packages/plug) support for [HMAC](https://en.wikipedia.org/wiki/HMAC) authentication. This is used for authentication between server sides.
![plug_hmac_auth](https://user-images.githubusercontent.com/13026209/82128415-46d6ab00-97e5-11ea-8c92-89f88d726b9a.png)
## Installation
This package can be installed by adding `plug_hmac_auth` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:plug_hmac_auth, "~> 0.1.0"}
]
end
```
## Usage
Here we demonstrate the usage by [this example](https://github.com/flipay/plug_hmac_auth_example). Replace the `PlugHmacAuthExample` by the name of your own web site.
### PlugHmacAuthExampleWeb.Endpoint
We use some raw data as [payload](https://github.com/flipay/plug_hmac_auth/blob/a978ac5051686ce1a9539a315a062009fd2045ae/lib/plug_hmac_auth.ex#L76) to verify the request from client.
For those `GET` requests, we use `query string` as payload.
For other requests, we use `raw body` as payload. But the raw body of request can only be read once. That means we can't read the raw body after the `Plug.Parsers`. Instead of the original body reader provided by `Plug.Parsers`, we need to use a custom body reader to cache the `raw body`.
```elixir
plug Plug.Parsers,
parsers: [:urlencoded, :multipart, :json],
pass: ["*/*"],
json_decoder: Phoenix.json_library(),
body_reader: {PlugHmacAuth.BodyReader, :read_body, []}
```
### PlugHmacAuthExampleWeb.Router
In the router module of your web site, define a new pipeline to enable the plug of HMAC authentication:
```elixir
pipeline :plug_hmac_auth do
plug(PlugHmacAuth,
key_access_id: "x-access-id",
key_signature: "x-access-signature",
hmac_hash_algo: :sha512,
secret_handler: PlugHmacAuthExample.Handlers.SecretHandler,
error_handler: PlugHmacAuthExampleWeb.ErrorHandler
)
end
```
Module `PlugHmacAuth` needs these options:
- `key_access_id`: The key of `access_id` in the HTTP request header.
- `key_signature`: The key of `signature` in the HTTP request header.
- `hmac_hash_algo`: The algorithm of HMAC.
- `secret_handler`: Secret handler is the module to get the `secret` by given `access_id`.
- `error_handler`: Error handler is the module to handle the unauthorized request.
### HMAC hash algorithm
[Here](https://github.com/flipay/plug_hmac_auth/blob/a978ac5051686ce1a9539a315a062009fd2045ae/lib/plug_hmac_auth.ex#L12) lists the algorithms current supported.
### Secret Handler
We need to implement the callback function of `get_secret_key/1` to let authenticator know how to get the secret key by given access id.
### Error Handler
We need to implement the callback function of `auth_error/2` to let the authenticator know how to handle the unauthorized request.
## Documentation
See [HexDocs](https://hexdocs.pm/plug_hmac_auth).
## Reference
- [Demo API Server Using This HMAC Authentication Plug](https://github.com/flipay/plug_hmac_auth_example)
- [HMAC Authentication: Better protection for your API](https://dev.to/pim/hmac-authentication-better-protection-for-your-api-4e0)