JWT Based Security
Securing the application with JSON Web Tokens
Securing the App#
Up until this point, we have been making great progress, but our backend API is unsecured. We will address security in this module by using JSON Web Tokens (JWTs).
JWTs are an industry-standard way of representing identity that can be used to authenticate and authorize an API call.
Once you have an actual JWT, the security mechanism is pretty straight forward. You attach the JWT to your API request header and then the backend API validates the JWT prior to handling the request.
Here's an example API request with a JWT:
GET /api/lunch-week
Header
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjVoc1FKZ3BKdU9fV3FVLTdCQUd3ViJ9.eyJpc3MiOiJodHRwczovL2Rldi0tNmFlOGJ4aS51cy5hdXRoMC5jb20vIiwic3ViIjoiYXV0aDB8NWY0YTcwYTZjNjQ3OGIwMDY3ZDg2ODk1IiwiYXVkIjpbImh0dHBzOi8vZGV2LS02YWU4YnhpLnVzLmF1dGgwLmNvbS9hcGkvdjIvIiwiaHR0cHM6Ly9kZXYtLTZhZThieGkudXMuYXV0aDAuY29tL3VzZXJpbmZvIl0sImlhdCI6MTU5OTg1OTcwOSwiZXhwIjoxNTk5OTQ2MTA5LCJhenAiOiI4SEx5VVhTSkd3NWI0MW5ob1U1MmVVaFA3OUwyeDlPNSIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwifQ.nJvx5iNdZvUHDTTcBzEIe_uIqzKDSMF-F-_tpKNl-YIlm3W_u-A-TorkZZV7qYnEJ4BiEOdKuzZtrvyRYRKLYvr7HEJwXrqWsUs8NHcLlnkxmeEkagMFRpx9L_S8ZP_owfjzY0TbddL-xSE7OwKZLkYtK8TKy1b1I2DsKuIozwNKGm-vhAowYUmGCvBtBl3-MaVPvJT10tEeDJuHTGukEK6TWeFCi3BKPdRmn1W0t0_UPwL270wYUw5G-PdvO-IAZS9RHjE6Vh2tg8vR2AbBVZvXTkYiBLJbRpJ53LkwzwIClLn4RVHUqapHG-xxGEYBP--zGHn5xaOUjJ7pd-25Nw
For this course, we are going to integrate with Auth0, a third party service. Auth0 will generate JWTs and manage users for our app. To get started, head over to https://auth0.com and sign up for a free account.

Creating an Auth0 Application#
Once you get logged into the Auth0 dashboard, navigate to the Applications section and Create Application. Choose the Single Page Application option. You can call the application school-lunch-frontend
:

Creating a Test User#
Next, go to the Users & Roles menu and choose Create User. Complete the form to create a test user, making sure to remember the password you use.

Integrating Auth0 with the Frontend Application#
We need to take a few steps to integrate Auth0 into the frontend Svelte application. Here's an overview of how this process will work:
For frontend lunch administration pages that need security, determine whether the user is currently authenticated
If the user is not authenticated, redirect the user to the Auth0 login page and provide Auth0 with a callback URL
The user logs in and Auth0 redirects the user back to the callback URL provided in step 2
When Auth0 redirects back, it will provide a special code in the callback URL, e.g., http://localhost:5000/callback/code=kjsdlnliksdfsdf
The Svelte app will then parse the callback URL and receive the user's JWT
Store the user's JWT in the browser's
localStorage
so that it will be persistent across tabs and available for API calls
Ok, it's a lot of steps and sounds complicated, but hopefully it will make more sense as we work through the code.
First, install the Auth0 SPA library in the frontend application:
$ npm install @auth0/auth0-spa-js@1.12.0
Next, we are going to update the AdminLayout
component that we already use for all Admin pages. We'll add our Auth0 onMount code and a logout button.
Working with AdminLayout.svelte
add a Logout
button to the markup and stub out a logout function:
<script>
other script stuff
const logout = async () => {
// todo
}
</script>
<div>
{#if initialized}
<button class="button is-light is-small" style="float: right;" on:click="{() => logout()}">Logout</button>
<Route {currentRoute} />
{/if}
</div>
Now, we can use the Auth0 library in the onMount
function and handle authentication, but first, there are a couple of places where we will need Auth0 config, so go ahead and create a file called auth0-config.js
in the frontend/src
directory of the project.
You can find the config values needed by looking at the school-lunch-frontend
Application in the Auth0 console.
// src/auth0-config.js
const auth0Config = {
audience: 'https://<YOUR AUTH0 DOMAIN>/api/v2/',
domain: '<YOUR AUTH0 DOMAIN>',
client_id: '<YOUR AUTH0 CLIENT ID>',
cacheLocation: 'localstorage',
}
export default auth0Config
Back to the AdminLayout.svelte
file, import auth0-config
and createAuth0Client
. Then we'll add a bit of code to check the authentication state of the current user. If the current user is not authenticated, then redirect to Auth0 for login.
Update the onMount
function to add the following Auth0 related code. For now, we're still setting a test user in the user
store. We'll address this in the next lesson.
import createAuth0Client from '@auth0/auth0-spa-js'
import auth0Config from '../../auth0-config'
onMount(async () => {
let auth0 = await createAuth0Client(auth0Config)
const authenticated = await auth0.isAuthenticated()
if (!authenticated) {
await auth0.loginWithRedirect({
redirect_uri: `${window.location.origin}/callback`,
appState: window.location.pathname,
})
} else {
user.set({
name: 'Test User',
schoolName: 'Test School',
})
initialized = true
}
})
At this point, if we go to test this code, we'll get an error in the browser's console. We need to set Allowed Callback URLs and Allowed Web Origins in the Auth0 dashboard.
In Auth0 under Applications > school-lunch-frontend > Settings, add the following:
Add
http://localhost:5000
andhttp://localhost:5000/callback
to the Allowed Callback URLs field.Add
http:/localhost:5000
to the Allowed Web Origins field.Add
http:/localhost:5000
to the Allowed Logout URLs field as well.
This page is a preview of Fullstack Svelte