feat: add user authentication with separate login and register pages
- Custom User model with email as unique identifier (AUTH_USER_MODEL) - POST /api/auth/register/ with email validation, password min 8 chars, duplicate rejection - POST /api/auth/login/ returning JWT (access + refresh) tokens - Passwords hashed via Django's make_password - React LoginPage and RegisterPage with form validation - AuthContext with useReducer for auth state management - Axios API client with JWT token injection - TypeScript conversion of frontend scaffold
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
import axios from "axios";
|
||||
|
||||
const apiClient = axios.create({
|
||||
baseURL: import.meta.env.VITE_API_URL || "http://localhost:8000",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
|
||||
// Attach access token to every request if present
|
||||
apiClient.interceptors.request.use((config) => {
|
||||
const token = localStorage.getItem("access_token");
|
||||
if (token && config.headers) {
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
}
|
||||
return config;
|
||||
});
|
||||
|
||||
export interface RegisterPayload {
|
||||
email: string;
|
||||
password: string;
|
||||
password_confirm: string;
|
||||
first_name?: string;
|
||||
last_name?: string;
|
||||
}
|
||||
|
||||
export interface LoginPayload {
|
||||
email: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export interface UserProfile {
|
||||
id: number;
|
||||
email: string;
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
}
|
||||
|
||||
export interface LoginResponse {
|
||||
user: UserProfile;
|
||||
access: string;
|
||||
refresh: string;
|
||||
}
|
||||
|
||||
export function registerUser(payload: RegisterPayload): Promise<UserProfile> {
|
||||
return apiClient
|
||||
.post<UserProfile>("/api/auth/register/", payload)
|
||||
.then((res) => res.data);
|
||||
}
|
||||
|
||||
export function loginUser(payload: LoginPayload): Promise<LoginResponse> {
|
||||
return apiClient
|
||||
.post<LoginResponse>("/api/auth/login/", payload)
|
||||
.then((res) => res.data);
|
||||
}
|
||||
Reference in New Issue
Block a user