Compare commits

...

1 Commits

Author SHA1 Message Date
dff3074f8c httpOnly cookie attempt 1 2024-06-17 18:15:11 +05:30
4 changed files with 79 additions and 38 deletions

39
auth.py
View File

@ -5,8 +5,8 @@ from typing import Any, Union
import bcrypt import bcrypt
import jwt import jwt
from fastapi import Depends, HTTPException, status from fastapi import Cookie, Depends, HTTPException, status
from fastapi.security import HTTPBearer from fastapi.security import HTTPBearer, OAuth2PasswordRequestForm
from jwt.exceptions import InvalidTokenError from jwt.exceptions import InvalidTokenError
ACCESS_TOKEN_EXPIRE_MINUTES = 30 # 30 minutes ACCESS_TOKEN_EXPIRE_MINUTES = 30 # 30 minutes
@ -38,6 +38,7 @@ def get_current_user(token: str = Depends(security)) -> dict:
headers={'WWW-Authenticate': 'Bearer'} headers={'WWW-Authenticate': 'Bearer'}
) )
credential = token.credentials credential = token.credentials
try: try:
payload = jwt.decode(credential, JWT_SECRET_KEY, algorithms=[ALGORITHM]) payload = jwt.decode(credential, JWT_SECRET_KEY, algorithms=[ALGORITHM])
user_id: str = payload.get("sub") user_id: str = payload.get("sub")
@ -65,6 +66,40 @@ def get_current_user(token: str = Depends(security)) -> dict:
return cur_user return cur_user
def get_current_user2(token: str = Cookie(default=None)):
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
headers={'WWW-Authenticate': 'Bearer'}
)
print('TOKEN: ', token)
try:
payload = jwt.decode(token, JWT_SECRET_KEY, algorithms=[ALGORITHM])
user_id: str = payload.get("sub")
if user_id is None:
raise credentials_exception
except InvalidTokenError:
raise credentials_exception
with open('database/users.json', 'r') as f:
text = f.read()
if text:
data = json.loads(text)
else:
raise credentials_exception
user = [i for i in data if i['id']==user_id]
if not user:
raise credentials_exception
cur_user = {'id': user_id}
cur_user['username'] = user[0]['username']
cur_user['encryption_key'] = payload['key']
return cur_user
class Hasher: class Hasher:
"""Class for hashing and verifying passwords""" """Class for hashing and verifying passwords"""

View File

@ -29,10 +29,14 @@ export default {
methods: { methods: {
async login() { async login() {
const url = `${this.apiBaseUrl}/login`; const url = `${this.apiBaseUrl}/login`;
var formData = new FormData();
for (var key in this.form) {
formData.append(key, this.form[key]);
}
const requestOptions = { const requestOptions = {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, // headers: { "Content-Type": "application/json" },
body: JSON.stringify(this.form), body: formData,
}; };
const response = await fetch(url, requestOptions) const response = await fetch(url, requestOptions)
@ -47,9 +51,10 @@ export default {
}); });
console.log("response: ", response); console.log("response: ", response);
if ("message" in response) { if ("message" in response) {
if (response.message === "authenticated") { if (response.message === "Authenticated") {
const token = response.accessToken; // const token = response.accessToken;
sessionStorage.setItem("token", token); // sessionStorage.setItem("token", token);
sessionStorage.setItem("authenticated", true);
this.$emit("loggedin", true); this.$emit("loggedin", true);
} }
} }

View File

@ -100,13 +100,14 @@ export default {
methods: { methods: {
async listSecrets() { async listSecrets() {
const url = `${this.apiBaseUrl}/secret`; const url = `${this.apiBaseUrl}/secret`;
const token = sessionStorage.getItem("token"); // const token = sessionStorage.getItem("token");
const requestOptions = { const requestOptions = {
method: "GET", method: "GET",
headers: { credentials: "include",
"Content-Type": "application/json", // headers: {
Authorization: `Bearer ${token}`, // // "Content-Type": "application/json",
}, // // Authorization: `Bearer ${token}`,
// },
}; };
console.log(requestOptions); console.log(requestOptions);
const response = await fetch(url, requestOptions) const response = await fetch(url, requestOptions)

50
main.py
View File

@ -1,19 +1,15 @@
import json import json
from fastapi import Depends, FastAPI, HTTPException, status from fastapi import Depends, FastAPI, HTTPException, Response, status
from fastapi.encoders import jsonable_encoder from fastapi.encoders import jsonable_encoder
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from fastapi.security import OAuth2PasswordBearer from fastapi.security import OAuth2PasswordRequestForm
from auth import Hasher, create_access_token, get_current_user from auth import (Hasher, create_access_token, get_current_user,
from crypto import ( get_current_user2)
deserialize_into_bytes, from crypto import (deserialize_into_bytes, fernet_decrypt, fernet_encrypt,
fernet_decrypt, generate_random_encryption_key, generate_user_passkey,
fernet_encrypt, serialize_bytes)
generate_random_encryption_key,
generate_user_passkey,
serialize_bytes,
)
from models import Secret, User, UserLogin from models import Secret, User, UserLogin
app = FastAPI() app = FastAPI()
@ -22,7 +18,7 @@ app = FastAPI()
origins = [ origins = [
'http://localhost', 'http://localhost',
'http://localhost:5173', 'http://localhost:5173',
"*" # "*"
] ]
app.add_middleware( app.add_middleware(
CORSMiddleware, CORSMiddleware,
@ -81,7 +77,7 @@ async def register(user: User):
@app.post('/login') @app.post('/login')
async def login(user: UserLogin): async def login(response: Response, form_data: OAuth2PasswordRequestForm = Depends()):
"""logs in the user""" """logs in the user"""
users = [] users = []
@ -90,7 +86,10 @@ async def login(user: UserLogin):
if text: if text:
users.extend(json.loads(text)) users.extend(json.loads(text))
cur_user = [i for i in users if i['username']==user.username] username = form_data.username
password = form_data.password
cur_user = [i for i in users if i['username']==username]
if not cur_user: if not cur_user:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,
@ -99,7 +98,7 @@ async def login(user: UserLogin):
else: else:
cur_user = cur_user[0] cur_user = cur_user[0]
password_match = Hasher.verify_password(user.password, cur_user['password']) password_match = Hasher.verify_password(password, cur_user['password'])
if not password_match: if not password_match:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,
@ -108,16 +107,16 @@ async def login(user: UserLogin):
encrypted_encryption_key = cur_user['encryption_key'].encode() encrypted_encryption_key = cur_user['encryption_key'].encode()
salt = deserialize_into_bytes(cur_user['salt']) salt = deserialize_into_bytes(cur_user['salt'])
_, master_key = generate_user_passkey(user.password, salt) _, master_key = generate_user_passkey(password, salt)
encryption_key = fernet_decrypt(encrypted_encryption_key, master_key) encryption_key = fernet_decrypt(encrypted_encryption_key, master_key)
access_token = create_access_token(subject=cur_user['id'], encryption_key=encryption_key) access_token = create_access_token(subject=cur_user['id'], encryption_key=encryption_key)
response = { # response = {
'message': 'authenticated', # 'message': 'authenticated',
'accessToken': access_token # 'accessToken': access_token
} # }
response.set_cookie('token', value=access_token, max_age=1800, httponly=True, path='/')
return response return {'message': 'Authenticated'}
@app.post("/secret") @app.post("/secret")
@ -185,9 +184,9 @@ async def update_secret(secret: Secret, current_user: dict = Depends(get_current
@app.get('/secret') @app.get('/secret')
async def list_secret(current_user: dict = Depends(get_current_user)): async def list_secret(current_user: dict = Depends(get_current_user2)):
"""Returns the encrypted secrets of the user.""" """Returns the encrypted secrets of the user."""
print('cuuuuuurrrrr', current_user)
data = [] data = []
with open('database/secrets.json', 'r') as f: with open('database/secrets.json', 'r') as f:
text = f.read() text = f.read()
@ -207,10 +206,11 @@ async def list_secret(current_user: dict = Depends(get_current_user)):
@app.get('/validate-token') @app.get('/validate-token')
async def validate_token(current_user: dict = Depends(get_current_user)): async def validate_token(current_user: dict = Depends(get_current_user2)):
user_id = current_user['id'] user_id = current_user['id']
print("user_id: ", user_id) print("user_id: ", user_id)
if user_id is not None: if user_id is not None:
return {'message': 'authenticated'} return {'message': 'authenticated'}
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED) raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
# return {'message': "hello"}