Vue3+Axios调用FastAPI JWT登录接口报错:缺少username和password字段
问题
使用JWT实现登录功能时,通过Postman或FastAPI文档提交用户名和密码均可成功获取token,但Vue3搭建的登录表单提交时无法正常工作。FastAPI返回错误:
["query", "username"], msg: "field required", type: "value_error.missing"
password字段也报相同错误。已通过console.log确认前端输入的username和password已正常获取,但接口仍提示字段缺失。
相关代码如下:
Vue3 代码
export default { data() { return { username: '', password: '', accessToken: '', }; }, methods: { login() { const data = { username: this.username, password: this.password, }; axios.post('http://127.0.0.1:8000/login_users/token', data) .then(response => { this.accessToken = response.data.access_token; localStorage.setItem('accessToken', this.accessToken); }) .catch(error => { console.error('Error al iniciar sesión:', error); }); }, }, };
FastAPI 代码
@login_users.post("/token") def login(form_data: OAuth2PasswordRequestForm = Depends(), db: Session = Depends(get_db)): print("Username:", form_data.username) user = AuthenticationClass(db).authenticate_user(form_data.username, form_data.password) access_token_expires = timedelta(minutes=30) access_token_jwt = AuthenticationClass(db).create_token({'sub': str(user.rut)}, access_token_expires) return { "access_token": access_token_jwt, "rut": user.rut, "visual_rut": user.visual_rut, "rol_id": user.rol_id, "nickname": user.nickname, "token_type": "bearer" }
登录表单输入框代码
<input type="text" id="username" class="bg-white-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="RUT" required v-model="username" /> <input type="password" id="password" class="bg-white-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="Contraseña" required v-model="password" />
原因分析
FastAPI的OAuth2PasswordRequestForm依赖默认要求请求数据采用**application/x-www-form-urlencoded格式**(表单编码格式),而你当前Vue代码中用axios直接传递JSON对象时,请求的Content-Type是application/json,后端无法从表单编码的位置解析到username和password字段,因此提示字段缺失。
Postman和FastAPI文档能成功,是因为它们默认会以表单编码格式发送请求参数。
解决方法
有两种可行的解决方案,任选其一即可:
方案一:前端修改为发送表单编码格式数据
修改Vue的login方法,将JSON对象转换为URLSearchParams(对应application/x-www-form-urlencoded格式)后再发送:
methods: { login() { const formData = new URLSearchParams(); formData.append('username', this.username); formData.append('password', this.password); axios.post('http://127.0.0.1:8000/login_users/token', formData) .then(response => { this.accessToken = response.data.access_token; localStorage.setItem('accessToken', this.accessToken); }) .catch(error => { console.error('Error al iniciar sesión:', error); }); }, },
axios会自动为URLSearchParams类型的请求体设置正确的Content-Type头。
方案二:后端修改为接受JSON格式数据
自定义一个Pydantic模型来替代OAuth2PasswordRequestForm,让接口支持JSON格式的请求:
from pydantic import BaseModel from datetime import timedelta # 自定义登录请求模型 class LoginRequest(BaseModel): username: str password: str @login_users.post("/token") def login(form_data: LoginRequest, db: Session = Depends(get_db)): print("Username:", form_data.username) user = AuthenticationClass(db).authenticate_user(form_data.username, form_data.password) access_token_expires = timedelta(minutes=30) access_token_jwt = AuthenticationClass(db).create_token({'sub': str(user.rut)}, access_token_expires) return { "access_token": access_token_jwt, "rut": user.rut, "visual_rut": user.visual_rut, "rol_id": user.rol_id, "nickname": user.nickname, "token_type": "bearer" }
这样后端就能直接解析Vue发送的JSON格式数据,无需修改前端代码。
内容的提问来源于stack exchange,提问作者Jis
相关产品推荐
相关产品推荐

