Authentication is vital to modern server apps. Teo simplifies the
implementation of authentication. Authentication includes handling user signing
in sessions, generate and validate user's API tokens.
Setup the project
To setup a project, install the dependencies and do programming language
specific setups. In the
first article in the series,
we explained what each step does in this process. In this tutorial, we just
include the command for pasting.
Password
Let's create a simple password authentication. Paste this into a new file
named schema.teo.
Create a dot env file in the same directory.
Let's explain the newly introduced decorators and pipeline items one by one.
The authentication functionalities reside in Teo's std.identitynamespaceCONCEPT.
@identity.id specifies which field is used to fetch the user
@identity.checker specifies which field is used to validate credentials and
how to validate
@bcrypt.salt performs a Bcrypt salting transform
@bcrypt.verify verifies the input value against the stored one
@writeonly hides the field value from the output
@identity.tokenIssuer specifies which type of token it generates
$identity.jwt performs the JWT token generation
identity.identityFromJwt middleware decodes the JWT token and set the
identity to the request
identity.signIn is the template which defines the signIn handler
identity.identity is the template which fetches the user information from
the token in the header
Let's start the server and perform a signIn request.
Send this JSON input to /User/create to create a user.
Hide HTTP response
Send this JSON input to /User/signIn.
Hide HTTP response
We've create a token from this user. If you intentionally type the password
wrongly, an error response is returned.
Companion validations
Practically only something like username and pasword are not enough. A lot of
websites and apps integrates some third party image authentications to prevent
non-human access. As a framework, Teo doesn't integrate with any service
providers. Instead, it's easy to integrate any third-party service or identity
with Teo.
Replace the content of schema.teo with this.
We created a @identity.companion field which is @virtual. A virtual field
isn't stored into the database. Companion values are present when checking and
validating against the checker value. In this simple example, we just ensure
the image auth token value exists.
Restart the server and send this JSON input to /User/signIn.
Hide HTTP response
Without the image auth token, this signIn request would fail.
Custom expiration interval
The token expiration interval can be dynamic instead of static. Let's try an
example of frontend passed expiration interval. Replace the content of
schema.teo with this.
Starts the server again and send this to /User/signIn.
Hide HTTP response
Since this token is valid for 2 seconds, just paste the token to the header
and send this empty JSON input to /User/identity.
Headers:
Authorization: Bearer #your token#
Hide HTTP response
Blocked account
Practically accounts can be blocked from signing in. Implement account blocking
is quite easy. Just tell us what does it mean by invalid account.
Replace the content of schema.teo with this.
Let's disable the previously created account. Send this JSON input to
/User/update.
Hide HTTP response
Now the signIn handler doesn't work for him and token authentication always
failed.
Third-party integration
Teo provides an easy way for developers to integrate with third party identity
services such as signing in with Google, Facebook. For China developers, this
may be something like signing in with WeChat.
Update the the content of schema.teo with this.
Restart the server and let's create a new account with third party account
binded by sending this input to /User/create.
Hide HTTP response
Now try signing in with the third party id and token. Send this input to
/User/signIn.
Hide HTTP response
For the sake of simplicity, let's just use $valid to make every third party
token valid. In the next section, we'll demonstrate how to create a custom
pipeline item to validate user's credential input.
Phone number and auth code
Let's add some complexity by introducing phone number and auth code. Replace
the content of schema.teo with this.
Generate entities for writing our custom pipeline item $validateAuthCode.
Now let's init a Rust project and create the main program file. Run the command
and update files.
Notice that we changed the type of email field from String to String?. For
databases other than SQLite is all ok. However, SQLite disallows altering table
columns. Using SQLite is for our demo purpose as it doesn't require
installation. Just delete the database.sqlite file and let's have a new
database setup.
Start the server with the updated command.
Let's recreate the previously created user. Send this to /User/create.
Hide HTTP response
Let's send the auth code to this user. Send this JSON input to
/AuthCode/create.
Hide HTTP response
In practice, mark the code field with @writeonly to hide it from the
output, and set an expire time.
Now try to sign in with this auth code. Send this to /User/signIn. Remember
to replace the auth code with the one that you got.
Hide HTTP response
Now we can sign in with email and password, email and auth code, phone number
with password, phone number with auth code. Together with the third party
account bindings.
Going next
There are much more even greater things to explore with Teo. Authentication is
all about how to validate user's validity and generate tokens. In the next
tutorial, we'll learn how to protect APIs with permissions.