How to set cookies from `.htaccess` & how to access the auth header from a single page application, or static site.

leamsigc

Ismael Garcia

Posted on March 26, 2024

How to set cookies from `.htaccess` & how to access the auth header from a single page application, or static site.

How to set cookies from .htaccess and how to access the auth header from a single page application, or static site.

What is the use case for this ?

You have a single page application, that need to use the auth token to handle, CRUD operations.
But this application needs to be embedded on a mobile application, that will render the web application in a View with in the application.

But when they load the single page application they pass an auth header, but your application is a single page application, and you don’t have a service like Back-end For Front-end (BFF).

So one of the solutions, for this problem can be that you access the auth header from the .htaccess or nginx config and set cookies base on the value of the header.

For my use case, we are using Apache web server, so the .htaccess is the solution for this until we have a BFF.

Let’s start the implementation

From the .htaccess

  • [x] Check if there is auth header
# Extract Authorization header value
RewriteCond %{HTTP:Authorization} ^Bearer\s+(.+)$ [NC]

Enter fullscreen mode Exit fullscreen mode
  • [x] Extract the auth header token
# Set the value for the AUTH_TOKEN
RewriteRule .* - [E=AUTH_TOKEN:%1]

Enter fullscreen mode Exit fullscreen mode
  • [x] Create a cookie and save the cookie with the token value
# Set the cookie base on the header auth
Header set Set-Cookie "TOKEN_CONTAINER=%{AUTH_TOKEN}e; Path=/" env=AUTH_TOKEN

Enter fullscreen mode Exit fullscreen mode

Here is the final code for it:

# Extract Authorization header value

RewriteCond %{HTTP:Authorization} ^Bearer\s+(.+)$ [NC]

RewriteRule .* - [E=AUTH_TOKEN:%1]


Header set Set-Cookie "TOKEN_CONTAINER=%{AUTH_TOKEN}e; Path=/" env=AUTH_TOKEN


Enter fullscreen mode Exit fullscreen mode

Note:

***Remember that to access the auth header token the Access-Control-Allow-Origin need to be set it to the origin of the call

The Access-Control-Allow-Origin can’t be "*" base on this from MDN.

Credential is not supported if the CORS header 'Access-Control-Allow-Origin' is '*'

MDN URL

So you need to set the Access-Control-Allow-Origin to the actual domain name that you need, for example you can set the Access-Control-Allow-Origin as "*" for other routes and just filter a specific route that you need to access the auth header

Example:

# Set CORS header for /path-need-cors path

RewriteCond %{REQUEST_URI} ^/path-need-cors [NC]

RewriteRule .* - [E=CORS_ORIGIN:https://domainname.com]




# Set CORS header based on the determined origin
Header always set Access-Control-Allow-Origin "%{CORS_ORIGIN}e" env=CORS_ORIGIN

# Set CORS header if the CORS_ORIGIN variable is undefined or not set
Header always set Access-Control-Allow-Origin "*" env=!CORS_ORIGIN




Header always set Vary "Origin"
Header always set Access-Control-Allow-Headers "Accept, Accept-Encoding, Authorization, Content-Type, DNT, Origin, User-Agent, X-Requested-With"
Header always set Access-Control-Allow-Methods "GET, POST, OPTIONS"
Header always set Access-Control-Allow-Credentials "true"

Enter fullscreen mode Exit fullscreen mode

Step 2 in this example I’m using Vue

Now that you set the cookie on the .htaccess

  • [x] Check if the cookie have a value from JavaScript
  • [x] extract the token value
  • [x] Use the token to load user information
<script lang="ts" setup>

/**
*
* Load cookie and check the value then call the user info with the provided token
*
* @author Leamsigc <Ismael Garcia>
* @version 0.0.1
*
* @todo [ ] Test the component
* @todo [ ] Integration test.
* @todo [✔] Update the typescript.

*/  
//...other imports.

import { useCookies } from '@vueuse/integrations/useCookies';

const cookies = useCookies();
const COOKIE_TOKEN = ref(cookies.get('TOKEN_CONTAINER') as string);
const { state, actions } = useOidcStore();

//Delete cookie after accessing the value of it.
cookies.remove('TOKEN_CONTAINER');

if (COOKIE_TOKEN.value) {

const request = await AuthUserService.loadUserInformation({ refreshToken: COOKIE_TOKEN.value });
    if (request.status === 200) {
    request.data ? actions.value.setUser(new User(request.data as any)) : null;

    }
}

</script>

<template>
    <SuspenseWrapper>
        <template v-if="loading === 'success'">
            <UserComponent :component-key="'MyUserProfile'" />
        </template>
        <template v-else-if="loading === 'error'">
            <ErrorView @close-trigger="loading = 'idle'" />
        </template>
        <template v-else>
            <h2>Handle other use case</h2>
        </template>
    </SuspenseWrapper>
</template>

<style scoped></style>

Enter fullscreen mode Exit fullscreen mode
NOTE:

I’m using oidc-client-ts, so accessing the token help me to manually refresh the token and then set the value of the user in the oidc-client-ts storage and that manage the refresh of the user token on the single page application.

I can provide an example if anyone have questions.

Can someone submit this article to the Daily dev, I can't do my self no enough reputation just 10 at the moment

💖 💪 🙅 🚩
leamsigc
Ismael Garcia

Posted on March 26, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related