From a5b64db5564c8b74c6a3c3f5046349e4aecfa8d6 Mon Sep 17 00:00:00 2001 From: StarAppeal Date: Thu, 11 Sep 2025 05:34:26 +0200 Subject: [PATCH] use cookies for web instead of the localStorage for storing jwt key --- src/context/AuthProvider.tsx | 49 +++++++++++++++++++++++++----------- src/services/RestService.ts | 6 +++++ src/utils/secureStorage.ts | 28 +++++++++++++-------- 3 files changed, 57 insertions(+), 26 deletions(-) diff --git a/src/context/AuthProvider.tsx b/src/context/AuthProvider.tsx index 6bbe862..a18bb81 100644 --- a/src/context/AuthProvider.tsx +++ b/src/context/AuthProvider.tsx @@ -2,6 +2,7 @@ import React, {createContext, useContext, useEffect, useState} from "react"; import {getFromStorage, JWT_TOKEN_KEY, removeFromStorage, saveInStorage} from "@/src/utils/secureStorage"; import {RestService} from "@/src/services/RestService"; import {User} from "@/src/model/User"; +import {Platform} from "react-native"; type AuthContextType = { @@ -26,21 +27,25 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({children} useEffect(() => { const checkAuthStatus = async () => { - const storedToken = await getFromStorage(JWT_TOKEN_KEY); - if (storedToken) { - setToken(storedToken); - const user = await saveUser(storedToken); + if (Platform.OS === 'web') { + const user = await saveUser(null); setIsAuthenticated(!!user); } else { - setIsAuthenticated(false); + const storedToken = await getFromStorage(JWT_TOKEN_KEY); + if (storedToken) { + setToken(storedToken); + const user = await saveUser(storedToken); + setIsAuthenticated(!!user); + } else { + setIsAuthenticated(false); + } } setLoading(false); }; - checkAuthStatus(); }, []); - const saveUser = async (token: string): Promise => { + const saveUser = async (token: string | null): Promise => { const response = await new RestService(token).getSelf(); if (!response.ok || !response.data) { // token ist ungültig @@ -61,26 +66,36 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({children} console.log("Already authenticated"); return; } + setLoading(true); + setError(null); + const response = await new RestService(null).login(username, password); if (!response.ok) { console.error("Login failed:", response.data.message); setError(response.data.message!); setIsAuthenticated(false); + setLoading(false); return; } - const token = response.data.token!; - await saveInStorage(JWT_TOKEN_KEY, token); - setToken(token); + if (Platform.OS !== 'web') { + const token = response.data.token!; + await saveInStorage(JWT_TOKEN_KEY, token); + setToken(token); + } // Fehler zurücksetzen setError(null); // User laden und ERST DANN isAuthenticated setzen - const user = await saveUser(token); + const user = await saveUser(Platform.OS === 'web' ? null : response.data.token!); setIsAuthenticated(!!user); setLoading(false); }; const logout = async () => { - await removeFromStorage(JWT_TOKEN_KEY); + if (Platform.OS === 'web') { + await new RestService(null).logout(); + } else { + await removeFromStorage(JWT_TOKEN_KEY); + } setToken(null); setIsAuthenticated(false); setAuthenticatedUser(null); @@ -88,9 +103,13 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({children} const refreshUser = async () => { console.log("refreshUser") - console.log(token) - if (!token) return; - await saveUser(token); + if (Platform.OS === 'web') { + await saveUser(null); + } else { + console.log(token) + if (!token) return; + await saveUser(token); + } }; return ( diff --git a/src/services/RestService.ts b/src/services/RestService.ts index 19a2dac..eee164c 100644 --- a/src/services/RestService.ts +++ b/src/services/RestService.ts @@ -1,6 +1,7 @@ import axios, {AxiosInstance, Method} from 'axios'; import {makeRedirectUri} from "expo-auth-session"; import {SpotifyConfig, User} from "@/src/model/User"; +import {Platform} from "react-native"; const API_URL = process.env.EXPO_PUBLIC_API_URL; @@ -27,6 +28,7 @@ class RestService { this.api = axios.create({ baseURL: API_URL, timeout: 10000, // Set a timeout for requests + withCredentials: Platform.OS === 'web', }); this.api.interceptors.request.use( @@ -130,6 +132,10 @@ class RestService { ); } + async logout(): Promise> { + return this.request>('POST', '/auth/logout'); + } + private async request(method: Method, url: string, data?: any, headers?: any): Promise { try { const response = await this.api.request({ diff --git a/src/utils/secureStorage.ts b/src/utils/secureStorage.ts index 88b86a3..4c7ff93 100644 --- a/src/utils/secureStorage.ts +++ b/src/utils/secureStorage.ts @@ -7,26 +7,32 @@ export const JWT_TOKEN_KEY = "jwtToken"; export const THEME_KEY = "theme"; export const saveInStorage = async (key: string, value: string) => { + if (isWeb && key === JWT_TOKEN_KEY) { + return; + } if (isWeb) { - localStorage.setItem(key, value); // Web: localStorage + localStorage.setItem(key, value); } else { - await SecureStore.setItemAsync(key, value); // Mobile: SecureStore + await SecureStore.setItemAsync(key, value); } }; + export const getFromStorage = async (key: string): Promise => { - if (isWeb) { - const item = localStorage.getItem(key); - console.log("Item:", item); - return item; // Web: localStorage - } else { - const item = await SecureStore.getItemAsync(key); - console.log("Item:", item); - return item; // Mobile: SecureStore + if (isWeb && key === JWT_TOKEN_KEY) { + return null; } -}; + if (isWeb) { + return localStorage.getItem(key); + } else { + return await SecureStore.getItemAsync(key); + } +} export const removeFromStorage = async (key: string) => { + if (isWeb && key === JWT_TOKEN_KEY) { + return; + } if (isWeb) { localStorage.removeItem(key); // Web: localStorage } else {