From 79ed4b626e68327eefa6f416fb4c17d3fbd966be Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Mon, 3 Mar 2025 21:20:59 -0800 Subject: [PATCH] (UI) Fix session handling with cookies (#8969) * add cookieUtils * use utils for clearing cookies * on logout use clearTokenCookies * ui use correct clearTokenCookies * navbar show userEmail on UserID page --- .../src/app/onboarding/page.tsx | 9 +--- ui/litellm-dashboard/src/app/page.tsx | 1 + .../src/components/navbar.tsx | 6 ++- .../src/components/user_dashboard.tsx | 11 +++-- ui/litellm-dashboard/src/utils/cookieUtils.ts | 44 +++++++++++++++++++ 5 files changed, 58 insertions(+), 13 deletions(-) create mode 100644 ui/litellm-dashboard/src/utils/cookieUtils.ts diff --git a/ui/litellm-dashboard/src/app/onboarding/page.tsx b/ui/litellm-dashboard/src/app/onboarding/page.tsx index ff301d7a474..e46e46fcb54 100644 --- a/ui/litellm-dashboard/src/app/onboarding/page.tsx +++ b/ui/litellm-dashboard/src/app/onboarding/page.tsx @@ -20,14 +20,7 @@ import { } from "@/components/networking"; import { jwtDecode } from "jwt-decode"; import { Form, Button as Button2, message } from "antd"; - -function getCookie(name: string) { - console.log("COOKIES", document.cookie) - const cookieValue = document.cookie - .split('; ') - .find(row => row.startsWith(name + '=')); - return cookieValue ? cookieValue.split('=')[1] : null; -} +import { getCookie } from "@/utils/cookieUtils"; export default function Onboarding() { const [form] = Form.useForm(); diff --git a/ui/litellm-dashboard/src/app/page.tsx b/ui/litellm-dashboard/src/app/page.tsx index 33d52bc41ad..2612cab5946 100644 --- a/ui/litellm-dashboard/src/app/page.tsx +++ b/ui/litellm-dashboard/src/app/page.tsx @@ -211,6 +211,7 @@ export default function CreateKeyPage() { userID={userID} userRole={userRole} premiumUser={premiumUser} + userEmail={userEmail} setProxySettings={setProxySettings} proxySettings={proxySettings} /> diff --git a/ui/litellm-dashboard/src/components/navbar.tsx b/ui/litellm-dashboard/src/components/navbar.tsx index 325ad9c3595..9bdc0fe9b7e 100644 --- a/ui/litellm-dashboard/src/components/navbar.tsx +++ b/ui/litellm-dashboard/src/components/navbar.tsx @@ -8,8 +8,10 @@ import { UserOutlined, LogoutOutlined } from '@ant-design/icons'; +import { clearTokenCookies } from "@/utils/cookieUtils"; interface NavbarProps { userID: string | null; + userEmail: string | null; userRole: string | null; premiumUser: boolean; setProxySettings: React.Dispatch>; @@ -18,6 +20,7 @@ interface NavbarProps { const Navbar: React.FC = ({ userID, + userEmail, userRole, premiumUser, proxySettings, @@ -27,7 +30,7 @@ const Navbar: React.FC = ({ let logoutUrl = proxySettings?.PROXY_LOGOUT_URL || ""; const handleLogout = () => { - document.cookie = "token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;"; + clearTokenCookies(); window.location.href = logoutUrl; }; @@ -37,6 +40,7 @@ const Navbar: React.FC = ({ label: (

Role: {userRole}

+

Email: {userEmail || "Unknown"}

{userID}

Premium User: {String(premiumUser)}

diff --git a/ui/litellm-dashboard/src/components/user_dashboard.tsx b/ui/litellm-dashboard/src/components/user_dashboard.tsx index 8b9f5e328f0..22b47d525fc 100644 --- a/ui/litellm-dashboard/src/components/user_dashboard.tsx +++ b/ui/litellm-dashboard/src/components/user_dashboard.tsx @@ -21,6 +21,7 @@ import { useSearchParams, useRouter } from "next/navigation"; import { Team } from "./key_team_helpers/key_list"; import { jwtDecode } from "jwt-decode"; import { Typography } from "antd"; +import { clearTokenCookies } from "@/utils/cookieUtils"; const isLocal = process.env.NODE_ENV === "development"; if (isLocal != true) { console.log = function() {}; @@ -295,14 +296,15 @@ const UserDashboard: React.FC = ({ if (userID == null || token == null) { // user is not logged in as yet + console.log("All cookies before redirect:", document.cookie); + + // Clear token cookies using the utility function + clearTokenCookies(); + const url = proxyBaseUrl ? `${proxyBaseUrl}/sso/key/generate` : `/sso/key/generate`; - - // clear cookie called "token" since user will be logging in again - document.cookie = "token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;"; - console.log("Full URL:", url); window.location.href = url; @@ -326,6 +328,7 @@ const UserDashboard: React.FC = ({ } console.log("inside user dashboard, selected team", selectedTeam); + console.log("All cookies after redirect:", document.cookie); return (
diff --git a/ui/litellm-dashboard/src/utils/cookieUtils.ts b/ui/litellm-dashboard/src/utils/cookieUtils.ts new file mode 100644 index 00000000000..a09cf4e97f6 --- /dev/null +++ b/ui/litellm-dashboard/src/utils/cookieUtils.ts @@ -0,0 +1,44 @@ +/** + * Utility functions for managing cookies + */ + +/** + * Clears the token cookie from both root and /ui paths + */ +export function clearTokenCookies() { + // Get the current domain + const domain = window.location.hostname; + + // Clear with various combinations of path and SameSite + const paths = ['/', '/ui']; + const sameSiteValues = ['Lax', 'Strict', 'None']; + + paths.forEach(path => { + // Basic clearing + document.cookie = `token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=${path};`; + + // With domain + document.cookie = `token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=${path}; domain=${domain};`; + + // Try different SameSite values + sameSiteValues.forEach(sameSite => { + const secureFlag = sameSite === 'None' ? ' Secure;' : ''; + document.cookie = `token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=${path}; SameSite=${sameSite};${secureFlag}`; + document.cookie = `token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=${path}; domain=${domain}; SameSite=${sameSite};${secureFlag}`; + }); + }); + + console.log("After clearing cookies:", document.cookie); +} + +/** + * Gets a cookie value by name + * @param name The name of the cookie to retrieve + * @returns The cookie value or null if not found + */ +export function getCookie(name: string) { + const cookieValue = document.cookie + .split('; ') + .find(row => row.startsWith(name + '=')); + return cookieValue ? cookieValue.split('=')[1] : null; +} \ No newline at end of file