Where do I store jwt tokens in the front end using Nuxt3? Since Nuxt3 is all about server side rendering, I cannot store the tokens in local storage or any other client side storing option. I've read that the most secure option is using cookies that cannot be seen by JavaScript. Doesn't that mean that I cannot read or write the cookies myself? Even if I can see store the tokens in a cookie, doesn't that mean that other people can see the sensitive information? What is the best way? How do I use the cookies if cookies are the best option?

This is my current pinia store that handles the events using local storage, it worked fine if the pages are rendered client side, not sure about the security though

import { defineStore } from 'pinia';
import jwt_decode from 'jwt-decode';

const baseUrl = 'http://xx.xxx.xx.xxx:xxxx/auth'

export const useAuthStore = defineStore('auth', () => {
const user = ref<string | null>(null)
const isAuthorized = ref<boolean>(false)
const accessToken = ref<string | null>(null)
const refreshToken = ref<string | null>(null)
const expiresAt = ref<number | null>(null)

type returnToken = {
  token: string,
  refreshToken: string
}
type decodedToken = {
  name: string,
  sub: string,
  exp: number,
  iat: number
}

function login(tokens: returnToken) {
  const data: decodedToken = jwt_decode(tokens.token)
  const expire = data.exp * 1000

  user.value = data.sub;
  isAuthorized.value = true
  accessToken.value = tokens.token;
  refreshToken.value = tokens.refreshToken;
  expiresAt.value = expire;

  // Save the tokens to local storage
  localStorage.setItem('user', data.sub);
  localStorage.setItem('isAuthorized', String(true));
  localStorage.setItem('accessToken', tokens.token);
  localStorage.setItem('refreshToken', tokens.refreshToken);
  localStorage.setItem('expiresAt', String(expire));

  useRouter().push('/panel')
}

async function refresh(refresh: string) {
  // Get the refresh token from local storage
  // if(!refreshToken.value){
  //   refreshToken.value = localStorage.getItem('refreshToken') ? localStorage.getItem('refreshToken') : null
  // }
  

  // Send a request to the backend to refresh the access token
  const response = await fetch(baseUrl+'/refresh-token', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(
      {
        "refresh_token": refresh
      }
    )
  });

  // Check the response status code
  if (response.status === 201) {
    // The refresh token was successful
    const tokens = await response.json()
    const token = tokens.token
    const data: decodedToken = jwt_decode(token)
    
    user.value = data.sub;
    isAuthorized.value = true
    accessToken.value = token
    expiresAt.value = data.exp * 1000


    // Save the new access token to local storage
    localStorage.setItem('user', data.sub);
    localStorage.setItem('isAuthorized', String(true));
    localStorage.setItem('accessToken', accessToken.value ? accessToken.value : '');
    localStorage.setItem('expiresAt', String(expiresAt.value));
  } else {
    // The refresh token failed
    logout();
  }
}
function logout() {
  // Clear the user state and tokens
  user.value = null;
  isAuthorized.value = false;
  accessToken.value = null;
  refreshToken.value = null;
  expiresAt.value = null;

  // Remove the tokens from local storage
  localStorage.removeItem('user');
  localStorage.removeItem('isAuthorized');
  localStorage.removeItem('accessToken');
  localStorage.removeItem('refreshToken');
  localStorage.removeItem('expiresAt');

  useRouter().push('/')
}

return { user, isAuthorized, accessToken, refreshToken, expiresAt, login, refresh, logout }

});
0

There are 0 answers