Authorization
Alchemy provides built in support for Bcrypt hashing and automatic Basic or Token authentication via Rune & Middleware
.
Bcrypt
Standard practice is to never store plain text passwords in your database. Bcrypt is a password hashing function that creates a one way hash of a plaintext password. It’s an expensive process CPU-wise, so it will help protect your passwords from being easily cracked through brute forcing.
It’s simple to use, and runs asynchronously so as not to block the current thread.
If you’d rather run Bcrypt synchronously and block the current thread until it’s finished, you may use hashSync()
or verifySync()
.
Request Auth
Request
makes it easy to pull Authorization
information off an incoming request.
Authorization: Basic
You can access Basic
auth info via .basicAuth() -> HTTPAuth.Basic?
.
Authorization: Bearer
You can also get Bearer
auth info via .bearerAuth() -> HTTPAuth.Bearer?
.
Authorization: Either
You can also get any Basic
or Bearer
auth from the request.
Auth Middleware
Incoming Request
can be automatically authorized against your Rune Model
s by conforming your Model
s to “authable” protocols and protecting routes with the generated Middleware
.
Basic Auth Middleware
To authenticate via the Authorization: Basic ...
headers on incoming Request
s, conform your Rune Model
that stores usernames and password hashes to BasicAuthable
.
Now, put User.basicAuthMiddleware()
in front of any endpoints that need basic auth. When the request comes in, the Middleware
will compare the username and password in the Authorization: Basic ...
headers to the username and password hash of the User
model. If the credentials are valid, the Middleware
will set the relevant User
instance on the Request
, which can then be accessed via request.get(User.self)
.
If the credentials aren’t valid, or there is no Authorization: Basic ...
header, the Middleware will throw an HTTPError(.unauthorized)
.
Note that Rune is inferring a username at column "email"
and password at column "password"
when verifying credentials. You may set custom columns by overriding the usernameKeyString
or passwordKeyString
of your Model
.
Token Auth Middleware
Similarly, to authenticate via the Authorization: Bearer ...
headers on incoming Request
s, conform your Rune Model
that stores access token values to TokenAuthable
. Note that this time, you’ll need to specify a BelongsTo
relationship to the User type this token authorizes.
Like with Basic
auth, put the UserToken.tokenAuthMiddleware()
in front of endpoints that are protected by bearer authorization. The Middleware
will automatically parse out tokens from incoming Request
s and validate them via the UserToken
type. If the token matches a UserToken
row, the related User
and UserToken
will be .set()
on the Request
for access in a handler.
Note that Rune is again inferring a "value"
column on the UserToken
to which it will compare the tokens on incoming Request
s. This can be customized by overriding the valueKeyString
property of your Model
.