In this section, you learn how to set up your fullstack serverless application with Fauna.
π Final Code
Run the following command in your terminal to create a new Svelte application.
$ npm init svelte@next fauna-shop
The Svelte CLI gives you some options to customize our application. Choose the following options.
β Which Svelte app template? βΊ Skeleton project
β Use TypeScript? β¦ No
β Add ESLint for code linting? Β Yes
β Add Prettier for code formatting? Yes
Run the newly created application with the following command.
$ cd fauna-shop
$ npm i
$ npm run dev
Navigate to http://localhost:3000 in your browser and review the running application.
There are many popular libraries that you can use to consume GraphQL in Svelte. The @urql/svelte
library is one of the most popular ones. This workshop uses the @urql/svelte
library as its GraphQL client.
Run the following command to add the library in your project.
$ npm i @urql/svelte graphql --save
Next, create a new file src/client.js
in your application. Add the following code snippet to the file.
import { createClient } from '@urql/svelte';
/**
Uncomment the appropriate line according to the
region group where you created your database.
**/
// const url = 'https://graphql.eu.fauna.com/graphql'
// const url = 'https://graphql.us.fauna.com/graphql'
const url = 'https://graphql.fauna.com/graphql'
export default createClient({
url,
fetchOptions: () => {
const token = import.meta.env.VITE_PUBLIC_FAUNA_KEY;
return {
headers: { authorization: token ? `Bearer ${token}` : '' },
};
},
});
Region groups give you control over where your data resides. You choose the Region Group for your application when you create your database in the first chapter. To learn more about Region Groups visit the documentation.
In the previous code snippet, there is an environment variable called VITE_PUBLIC_FAUNA_KEY. You ship your client application with a Fauna secret that allows limited access to Fauna resources. A suggested practice is to limit this key to registering and authenticating users. Authenticated users then receive temporary access tokens when they login that grant access to additional resources.
First, create a role that only has permissions to call the RegisterUser and LoginUser functions you created in the User authentication section of the first chapter.
Navigate to the Security section of the Fauna dashboard and choose Roles then New Custom Role.
FrontEndRole
.When you invoke a UDF that does not have its own role, the UDF runs with the same permissions as the identity that invoked it. In the first section, you invoke your UDFs from the Shell and GraphQL sections of the dashboard. When you are in the dashboard, commands you invoke are run with admin permissions by default.
The key that you create for your front-end application only has permission to invoke the RegisterUser and LoginUser UDFs, but the UDFs need permission to create and read documents in the Owner collection. You do not want to give these permissions directly to the front-end role. Instead, create tightly-scoped roles for each UDF.
Return to the Security section of the dashboard and create another new role.
RegisterUserUDF
.Navigate to the Functions section, select the RegisterUser UDF, and update the role to use the new RegisterUserUDF role.
Navigate to the Shell and test your UDF by using the Run As feature to invoke the UDF as FrontEndRole.
To use the Run As feature, copy the following query, paste it into the web shell, select FrontEndRole from the Run As menu, and choose Run Query As to invoke your UDF.
Call(
"RegisterUser",
// ["email", "password", "name"]
["security@fauna-labs.com", "qZXUEhaNdng9", "Improved Security"]
)
{
ref: Ref(Collection("Owner"), "317182757128110665"),
ts: 1638747899080000,
data: {
email: "security@fauna-labs.com",
name: "Improved Security"
}
}
Create another new role named LoginUserUDF
. The LoginUser UDF needs permission to read from the findOwnerByEmail index to locate the correct user and to read from the Owner collection to compare the hashed credentials for that user.
Navigate to the Functions section and update the role of your LoginUser UDF to use the new LoginUserUDF role. Return to the Shell and test the UDF, again using Run As to invoke the UDF as the FrontEnd role.
Call(
"LoginUser",
// ["email", "password"]
["security@fauna-labs.com", "qZXUEhaNdng9"]
)
{
secret: "<token>",
ttl: Time("2021-12-06T00:56:46.768682Z"),
email: "security@fauna-labs.com"
}
Now that your roles and UDFs are working correctly, create a front-end key to store in your application. Navigate to the Security section and choose New Key.
Copy the secret key to use in the next step.
The secret key cannot be displayed once you navigate away from this page! If you lose a key, you can create a new key with the same role and revoke the old key.
Create a .env
file in the root of your application and add this secret key as an environment variable.
VITE_PUBLIC_FAUNA_KEY=fnxxxxxxxxxxxxx
Restart your Svelte application after updating the environment variable.
Run your application with the following command.
$ npm run dev
Open the src/routes/index.svelte
in your code and replace the contents with the following code. In the following code snippet, you have a simple button to test the login functionality. When the button is selected, it fires the login
mutation.
If you haven’t registered any users yet refer back to the Authentication section for instructions on signing up a new user.
<script>
import { setClient, mutation } from '@urql/svelte';
import client from '../client';
setClient(client);
const loginMutation = mutation({
query: `
mutation ($email: String!, $password: String!) {
login(email: $email, password: $password) {
secret
ttl
}
}
`,
});
async function testLogin(e) {
e.preventDefault();
const resp = await loginMutation({ email: "shadid12@email.com", password: "123456" })
console.log(resp.data);
}
</script>
<div>
<h3>Login Test</h3>
<button on:click={testLogin}>Login Test</button>
</div>
Make sure to replace the email
and password
with a valid email and password. Use a user you already registered in Authentication section.
Navigate to localhost:3000 and open your browser’s developer tools to the Console tab. Choose the Login button. You should see the response from the login mutation in the console!
In this session, you configured Fauna to perform user authentication with least privileged access and connected your front-end application to Fauna.
In the next section, you implement client-side user registration and login forms for your application.
π Get the final code for this section here