How to set cookies from `.htaccess` & how to access the auth header from a single page application, or static site.
Tags: vue, javascript, beginners, programming
Published: 2024-03-26 11:39:21




## 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 

```apache
# Extract Authorization header value
RewriteCond %{HTTP:Authorization} ^Bearer\s+(.+)$ [NC]

```



- [x] Extract the auth header token 

```apache
# Set the value for the AUTH_TOKEN
RewriteRule .* - [E=AUTH_TOKEN:%1]

```


- [x] Create a cookie and save the cookie with the token value 

```apache
# Set the cookie base on the header auth
Header set Set-Cookie "TOKEN_CONTAINER=%{AUTH_TOKEN}e; Path=/" env=AUTH_TOKEN

```



Here is the final code for it:



```apache
# 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


```



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](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSNotSupportingCredentials)



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:



```apache
# 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"

```






### 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 


```vue
<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>

```


##### 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.



{% gist https://gist.github.com/leamsigc/68d3f891d9298c35de273caa2b21e453 %} 



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