Protected shadow endpoints

Viewed 92

How can we implement SvelteKit protected shadow endpoints?

I want my selected shadow endpoints to return the value if the access_token in the cookies is valid. So, I want to be able to check validity of the token before. How can we have it without using boilerplate code everywhere and still have security?

1 Answers

A RequestHandler (a function exported by a page endpoint) receives (amongst other parameters) an http request. You could look inside that request to parse the cookies and validate a token stored inside them.

Here's an example using a fresh sveltekit project. It uses the cookie package to parse cookies from the headers:

in src/routes/index.svelte (a simple page that displays responseData returned by the endpoint):

<script>
  export let responseData 
</script>

<h1>Protected shadow endpoint</h1>
<p>Protected endpoint data:</p>
<p>{JSON.stringify(responseData)}</p>

in the endpoint src/routes/index.js:

import cookie from 'cookie'

/** @type {import('@sveltejs/kit').RequestHandler} */
export async function GET({ request }) {
  let responseData = null

  // parse the cookies from the headers and get the token
  const cookies = request.headers.get('cookie')
  const token = cookie.parse(cookies)?.access_token
  console.log('token', token)

  // check token validity
  if (token === 'abcd') {
    responseData = { msg: 'hello world' }
  } else {
    responseData = { msg: 'invalid token' }
  }
  return {
    body: {
      responseData,
    },
  }
}

To experiment with this fairly simple solution, you could use a hook to store a cookie in the upcoming requests to the index page.

[The handle function] runs every time the SvelteKit server receives a request — whether that happens while the app is running, or during prerendering — and determines the response.

In src/hooks.js:

/** @type {import('@sveltejs/kit').Handle} */
export async function handle({ event, resolve }) {
  let response = await resolve(event)

  // you can change this value to see how it reflects on the index page
  const token = 'abcd'

  if (event.url.pathname === '/') {
    // add a token cookie to requests accessing the index page
    response.headers.set('set-cookie', `access_token=${token};Path=/;HttpOnly`)
  }

  return response
}
Related