为什么这个API请求不能正常工作

问题描述 投票:0回答:1

我使用 Django-REST Framework 开发了一个 API,并尝试将其与我的前端连接。

我有一个端点来获得最后四名获胜者,当我尝试时它工作正常

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>
    
  )
}

但是,当我从 /login 登录,然后尝试从我的家获取当前登录的用户时,我收到一条错误消息,指出我未经身份验证。但是当我使用 Postman 执行相同操作时,它会正确返回用户。

这是我的/登录名:

'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>
        
    )
}

这就是我在主页上尝试做的事情

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>
  )
}

当我向 /user/login 发出 post 请求时,正确创建了 sessionid,当我在浏览器中访问 127.0.0.1:8000/user/user 时,我得到了登录的用户,这就是为什么我相信问题出在getUser(),但我无法解决它

请告诉我我是否清楚或者是否需要更多信息来帮助我。先谢谢你了

reactjs django next.js django-rest-framework next.js13
1个回答
0
投票

问题可能是 Django 后端未正确配置 CORS 策略,以允许使用来自 Next.js 前端的凭据进行跨域请求。

有几件事需要检查:

在 Django 设置中,确保安装并配置了 CORS 中间件,以允许使用凭据的 Next.js 源/域:

CORS_ALLOW_CREDENTIALS = True

CORS_ORIGIN_WHITELIST = [
    "http://localhost:3000" 
] 

CORS_ALLOW_METHODS = [
    "DELETE",
    "GET",
    "OPTIONS",
    "PATCH",
    "POST",
    "PUT",
]

在您看来,服务于/user/user,设置标头以允许凭据并公开响应标头:

response = JsonResponse({'username': user.username})
response["Access-Control-Allow-Credentials"] = "true"  
response["Access-Control-Expose-Headers"] = "*"
return response

在 Next.js 端,确保您的获取请求具有您拥有的凭据:“include”集。

这使得 CORS 策略能够传递会话 cookie。如果没有它,默认情况下跨域请求将被阻止发送或接收 cookie。

请告诉我这是否有助于解释问题!关键是在 Django 和 Nextjs 端正确启用 CORS 策略的凭据。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.