Commit b36c525e authored by Timothy J. Baek's avatar Timothy J. Baek
Browse files

enh: cookie auth

parent 1b100660
...@@ -2,6 +2,7 @@ import logging ...@@ -2,6 +2,7 @@ import logging
from fastapi import Request, UploadFile, File from fastapi import Request, UploadFile, File
from fastapi import Depends, HTTPException, status from fastapi import Depends, HTTPException, status
from fastapi.responses import Response
from fastapi import APIRouter from fastapi import APIRouter
from pydantic import BaseModel from pydantic import BaseModel
...@@ -47,7 +48,23 @@ router = APIRouter() ...@@ -47,7 +48,23 @@ router = APIRouter()
@router.get("/", response_model=UserResponse) @router.get("/", response_model=UserResponse)
async def get_session_user(user=Depends(get_current_user)): async def get_session_user(
request: Request, response: Response, user=Depends(get_current_user)
):
token = create_token(
data={"id": user.id},
expires_delta=parse_duration(request.app.state.config.JWT_EXPIRES_IN),
)
# Set the cookie token
response.set_cookie(
key="token",
value=token,
httponly=True, # Ensures the cookie is not accessible via JavaScript
secure=True, # Ensures the cookie is sent over https
samesite="lax",
)
return { return {
"id": user.id, "id": user.id,
"email": user.email, "email": user.email,
......
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from fastapi import HTTPException, status, Depends from fastapi import HTTPException, status, Depends, Request
from apps.webui.models.users import Users from apps.webui.models.users import Users
...@@ -24,7 +24,8 @@ ALGORITHM = "HS256" ...@@ -24,7 +24,8 @@ ALGORITHM = "HS256"
# Auth Utils # Auth Utils
############## ##############
bearer_security = HTTPBearer() bearer_security = HTTPBearer(auto_error=False)
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
...@@ -75,13 +76,24 @@ def get_http_authorization_cred(auth_header: str): ...@@ -75,13 +76,24 @@ def get_http_authorization_cred(auth_header: str):
def get_current_user( def get_current_user(
request: Request,
auth_token: HTTPAuthorizationCredentials = Depends(bearer_security), auth_token: HTTPAuthorizationCredentials = Depends(bearer_security),
): ):
# get token from cookie
token = request.cookies.get("token")
if auth_token is None and token is None:
raise HTTPException(status_code=403, detail="Not authenticated")
if auth_token is not None:
token = auth_token.credentials
# auth by api key # auth by api key
if auth_token.credentials.startswith("sk-"): if token.startswith("sk-"):
return get_current_user_by_api_key(auth_token.credentials) return get_current_user_by_api_key(token)
# auth by jwt token # auth by jwt token
data = decode_token(auth_token.credentials) data = decode_token(token)
if data != None and "id" in data: if data != None and "id" in data:
user = Users.get_user_by_id(data["id"]) user = Users.get_user_by_id(data["id"])
if user is None: if user is None:
......
...@@ -90,7 +90,8 @@ export const getSessionUser = async (token: string) => { ...@@ -90,7 +90,8 @@ export const getSessionUser = async (token: string) => {
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
Authorization: `Bearer ${token}` Authorization: `Bearer ${token}`
} },
credentials: 'include'
}) })
.then(async (res) => { .then(async (res) => {
if (!res.ok) throw await res.json(); if (!res.ok) throw await res.json();
......
...@@ -92,15 +92,15 @@ export const getFileById = async (token: string, id: string) => { ...@@ -92,15 +92,15 @@ export const getFileById = async (token: string, id: string) => {
return res; return res;
}; };
export const getFileContentById = async (token: string, id: string) => { export const getFileContentById = async (id: string) => {
let error = null; let error = null;
const res = await fetch(`${WEBUI_API_BASE_URL}/files/${id}/content`, { const res = await fetch(`${WEBUI_API_BASE_URL}/files/${id}/content`, {
method: 'GET', method: 'GET',
headers: { headers: {
Accept: 'application/json', Accept: 'application/json'
authorization: `Bearer ${token}` },
} credentials: 'include'
}) })
.then(async (res) => { .then(async (res) => {
if (!res.ok) throw await res.json(); if (!res.ok) throw await res.json();
......
...@@ -104,7 +104,7 @@ ...@@ -104,7 +104,7 @@
type="button" type="button"
on:click={async () => { on:click={async () => {
if (file?.url) { if (file?.url) {
getFileContentById(localStorage.token, file.id).then((blob) => { getFileContentById(file.id).then((blob) => {
if (blob) { if (blob) {
const url = URL.createObjectURL(blob); const url = URL.createObjectURL(blob);
window.open(url, '_blank').focus(); window.open(url, '_blank').focus();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment