I developed an API using Django-REST Framework and am trying to connect it with my frontend.
I have an endpoint to get the last four winners, and when I try it works alright
async function getLastFourWinners() {
const url = 'http://127.0.0.1:8000/bets/get_last_four_winners'
const response = await fetch(url)
if (!response.ok) {
throw new Error('Failed to fetch data')
}
return response.json()
}
export default async function Home() {
const winners = await getLastFourWinners()
return (
<main>
{winners.map((winner, index) => (
<LastWinnerItem
key={index}
username={winner.username}
roundName={winner.round}
leagueName={winner.league}
nPoints={winner.points}
nPlayers={winner.n_players}
pool={winner.pool}
imagePath={winner.profile_image}
/>
))}
</main>
)
}
However, when I login from /login and then try to get the current logged user from my home, I get an error saying that I am not authenticated. But when I do the same using Postman it returns the user properly.
This is my /login:
'use client'
import { useState } from 'react'
import { useRouter } from 'next/navigation'
import './login.css'
export default function Login() {
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const router = useRouter()
const url = 'http://127.0.0.1:8000/user/login/'
const handleLogin = async(e) => {
e.preventDefault();
try {
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({username, password}),
credentials: 'include',
})
console.log(response)
if (response.ok) {
// router.push('/')
console.log('ok')
} else {
console.error('Login failed')
}
} catch(error) {
console.error('Error during login')
}
}
return (
<main className='container__main py-4'>
<div className="card o-hidden border-0 shadow-lg w-75 mx-auto my-4">
<div className="card-header py-3 login__header">
<h4 className="m-0 font-weight-bold">Log in</h4>
</div>
<div className="card-body">
<form onSubmit={handleLogin}>
<input
type="text"
id="username"
name="username"
value={username}
onChange={(e) => setUsername(e.target.value)}
className="form-control mb-4"
placeholder="Username..."
required
/>
<input
type="password"
id="password"
name="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
className="form-control mb-4"
placeholder="Password..."
required
/>
<small>Do not have a user? <a href="/signup" className='signup__btn'>Sign up</a></small>
<div className="login__button d-flex justify-content-center">
<button type="submit" className="btn text-center px-5 py-2 align-items-center">LOG IN</button>
</div>
</form>
</div>
</div>
</main>
)
}
And this is what I am trying to do from my homepage
async function getUser() {
const response = await fetch('http://127.0.0.1:8000/user/user', {
method: 'GET',
credentials: 'include'
})
if(!response.ok) {
throw new Error('Failed to fetch data')
} else {
return response.json()
}
}
export default async function Home() {
const user = await getUser()
return (
<main>
<p>{user.username}</p>
</main>
)
}
The sessionid is created rightly when I make the post request to /user/login, and when I go to 127.0.0.1:8000/user/user in my browser I get the logged user, that is why I believe the problem is in getUser(), but am not being able to solve it
Please tell me if I was clear or if more information is needed to help me. Thank you in advance
2
Answers
I found the solution. The cookies were not being sent, so I was not sending the sessionid and the csrftoken to the server.
This is the solution using the app directory structure:
The issue is likely that the CORS policy is not properly configured on the Django backend to allow cross-origin requests with credentials from the Next.js frontend.
There are a few things to check:
In your Django settings, make sure you have the CORS middleware installed and configured to allow the Next.js origin/domain with credentials:
In your view that serves /user/user, set the headers to allow credentials and expose response headers:
On the Next.js side, ensure your fetch request has credentials: ‘include’ set, which you have.
This enables the CORS policy to pass the session cookie on. Without it, cross-origin requests are blocked from sending or receiving cookies by default.
Let me know if this helps explain the issue! The key is enabling credentials properly on both the Django and Nextjs side for the CORS policy.