Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
October 6, 2021 03:47 am GMT

User authentication in Fauna (an opinionated guide)

In this blog post, you learn the fundamentals of authenticating users in Fauna. You ship your client applications with a secret token from Fauna that has limited privileges. Ideally, this token can only register and login users in Fauna. Authenticated users then receive a temporary access token that they can use to access the Fauna resources securely. User-defined functions (UDFs) are the key to this implementation.

Pre-requisites

Some familiarity with FQL will be helpful. You can still follow along without any prior knowledge of FQL. To learn more about FQL visit this series of articles .

Solution overview

In this post, you:

  1. Create a new /secret key/in Fauna.

  2. Configure a role for the /secret key/so that your client application can only invoke the User Registration and Login UDFs using this key.

  3. Ship the secret key as an environment variable with your client application.

  4. Run the User Registration UDF from the client application using the /secret key/ to create a new user.

  5. Run the Login UDF from the client application to acquire a /user access token/.

  6. Use the /user/ /access token/ in the client application to interact with Fauna resources.

The following diagram demonstrates the overall authentication flow.

authentication flow diagram

User registration

Head over to the Fauna dashboard and create a new database.

Creating a new database

Select Collections and create a new collection called Account
Creating a new collection

The Account collection contains all user data. Navigate toIndexesand selectNew Index. Select Account as the source collection. Name the index account_by_email. You use this index to query users by their email address. In theTermsfield, input email. Make sure to select theUniqueoption and theSerializedoption to ensure that each user has a unique email address. Select Save to create the new index.

Creating a new index

Next, create a function to register new users. Select Functions from the dashboard menu and select NEW FUNCTION to create a new user-defined function (UDF).

Creating a UDF

Name your function UserRegistration and enter the following code in the Function Body. You can leave the role as None for now. Select Save to create your function.

Query(    Lambda(["email", "password"],        Create(Collection("Account"), {            credentials: { password: Var("password") },            data: {                email: Var("email")            }        })    ))

Creating a new user-defined function

Navigate to the Shell and register a new user by calling the UserRegistration UDF. Enter the following code in the shell and select Run Query.

Call("UserRegistration", "[email protected]", "pass123456")

Calling a UDF from the dashboard shell

Navigate back to Collections > Account and confirm that a new user is created.

User login

Return to the Functions tab, create a new function, and name it UserLogin. Add the following code snippet to your function body and select Save. Notice there is a ttl argument in the Login function. This ensures that the generated token expires after the specified time.

Query(    Lambda(["email", "password"],        Login(            Match(Index("account_by_email"), Var("email")),            {                 password: Var("password"),                ttl: TimeAdd(Now(), 3600, "seconds")            },        )    ))

Navigate back to the shell and call the function with the user's credentials.

Call("UserLogin", "[email protected]", "pass123456")

The output of this function gives you a secret token. Following is a sample response from the UDF. Take a note of the secret.

{  ref: Ref(Ref("tokens"), "310382039289299523"),  ts: 1632262229150000,  ttl: Time("2021-09-21T22:20:29.019666Z"),  instance: Ref(Collection("Account"), "310358409884992069"),  secret: "fnEE....."}

You can now use this secret token to access your Fauna resources from a client application. Verify the validity of the token by running the following CURL command in your terminal, replacing <YOUR_TOKEN> with the value of the secret your function returns.

curl https://db.fauna.com/tokens/self  -u <YOUR_TOKEN>
{  "resource": {    "ref": {      "@ref": {        "id": "310382039289299523",        "class": { "@ref": { "id": "tokens" } }      }    },    "ts": 1632262229150000,    "ttl": { "@ts": "2021-09-21T22:20:29.019666Z" },    "instance": {      "@ref": {        "id": "310358409884992069",        "class": {          "@ref": {            "id": "Account",            "class": { "@ref": { "id": "classes" } }          }        }      }    },    "hashed_secret": "$2a$05$Ta2ScWEQhV39VTKLmmXXXOxnpQlXvloLSd3g9nP2Gsb.zJMP6QK6y"  }}

Next, navigate to Collections and create a new collection called Movie. Populate your collection with the following sample data.

{    "title": "Reservoir Dogs",    "director": "Quentin Tarantino",    "release": "Jan 21, 1992"}{    "title": "The Hateful Eight",    "director": "Quentin Tarantino",    "release": "December 25, 2015"}{    "title": "Once Upon a Time in Hollywood",    "director": "Quentin Tarantino",    "release": "July 26, 2019"}

You will query this collection with the authenticated user's token in the next section.

Connecting Fauna with the client application

Your client application should have limited access to your Fauna backend. An unauthenticated user should only be able to call UserLogin and UserRegistration functions from your client application. It is best practice to follow the principle of least privilege .

Create a new role for your unauthenticated users. Navigate to Security > Roles and select New Custom Role.

Creating a custom role

Name your role UnAuthRole. Give the privilege to execute UserLogin and UserRegistration. As your functions are using the account_by_email index, provide read access to account_by_email as well. Also, provide read and create access to Account collection because UserLogin and UserRegistration UDFs need to read and create permission to this collection.

Collection permission

Function permission

Next, generate a security key for your UnAuthRole. Navigate to *Security > Keys > New Ke*y.

Creating a new key

Make sure to select UnAuthRole from the role options for your new key.

New key name and role configuration

Key Secret

You ship this key as an environment variable in your client application. Your client application can use this key to call only the UserRegistration and UserLogin function. You can not access any other resources in Fauna with this key.

To test this navigate to the Shell from the Fauna dashboard and select Run Query As > Specify a Secret Option. In the secret field input your key.

Running a query with a specified key

Run the following command in the shell.

Call("UserRegistration", "[email protected]", "pass12345"")
Call("UserRegistration", "[email protected]", "pass12345"){  ref: Ref(Collection("Account"), "311012249060770373"),  ts: 1632863244095000,  data: {    email: "[email protected]"  }}

Notice, that this will register a new user. Try accessing any other resources (i.e. Movie collection) using the same key. Run the following command in the shell.

Get(Documents(Collection("Movie")))
// OutputError: [  {    "position": [],    "code": "permission denied",    "description": "Insufficient privileges to perform the action."  }]

Review the output in the shell. You get an "Insufficient privileges to perform the action." error. It throws this error because the specified key doesnt have the privilege to access the Movie collection. This means the key is working as intended.

Next, run the UserLogin function in the shell.

Call("UserLogin", "[email protected]", "pass12345")

Review the output. The function returned a secret.

{  ref: Ref(Ref("tokens"), "311013644284461635"),  ts: 1632864574726000,  ttl: Time("2021-09-28T21:39:34.245802Z"),  instance: Ref(Collection("Account"), "311012249060770373"),  secret: "fnEEUPFC--ACQwROmU7CwAZDlUcF9R3liL1iaNf9y80UQgc_qLI"}

This secret is your temporary access token that can access other resources in Fauna. However, when you try to use it now to access the Movie collection you get the same error. This is because you have not yet defined what resources does this token has access to*.* In the next section, you learn how to give your user access tokens permission to certain resources.

Authenticated user role

Navigate to Security > Roles > New Role to Create a new user role. Name your role AuthRole and provide read, write, and create privileges on the Movie collection.

Configuring role privileges

Select the Membership tab and add the Account collection as a member.

Role membership

Run the UserLogin function again with the same credentials. Input the generated secret (user access token) next to the Specify a secret field in the shell.

specify secret

Run the following command to query Movie collection. Notice this time it returns a successful response.

Get(Documents(Collection("Movie")))
// Output{  ref: Ref(Collection("Movie"), "310384575062737476"),  ts: 1632264647455000,  data: {    title: "The Hateful Eight",    director: "Quentin Tarantino",    release: "December 25, 2015"  }}

User logout

Navigate to the function section of your Fauna dashboard. Define a new UDF called UserLogout and add the following code snippet in the function body.

Query(    Lambda("x", Logout(true)))

Make sure to assign AuthRole to UserLogout UDF.

Navigate to Security > Roles > AuthRole and assign call privilege to UserLogout UDF.

Assigning the privilege to run a UDF

Calling this UDF invalidates your secret token. You call this function with the following command.

Call("UserLogout")

Conclusion

In this post, you learn how to use UDF to do user authentication in Fauna. For more about advanced Authentication strategies (i.e., Token refresh) in Fauna, review this post. If you are interested in using third-party identity providers with Fauna, take a look at the Fauna and Auth0 integration post. Want to use AWS Cognito as an auth provider with Fauna? Take a look at the AWS Cognito and Fauna article.

If you enjoyed this article and want to see more articles like this one, let us know in the community forum.


Original Link: https://dev.to/fauna/user-authentication-in-fauna-an-opinionated-guide-51bb

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To