Gatsby应用登录认证逻辑异常:任意账号均提示登录成功
解决Gatsby登录逻辑总是提示成功的问题
看起来你的登录功能有几个关键问题导致无论输入什么账号密码都提示成功,我来一步步帮你排查和修复:
问题分析
- Mock API 响应逻辑限制:你使用的这个Mock接口大概率是无论请求内容如何都返回200成功状态,所以
response.ok永远为true,自然会一直触发登录成功的提示。我们需要在前端加入账号密码的校验逻辑,来匹配你预期的验证规则。 - 请求Body格式错误:你直接把
{ state }作为请求Body,但fetch要求请求体是字符串格式,没有用JSON.stringify转换会导致请求格式异常,不过Mock接口可能忽略了这个问题依然返回成功。 - State更新顺序错误:
setState({ "loading": true, ...state });里...state会覆盖前面的loading: true(因为原state里的loading是false),导致loading状态没有被正确设置。 - 未定义变量错误:
navigate(/success, { "state": { email } });中的email变量未定义,应该使用state.email。
修复后的完整代码
import React, { ReactElement, useState } from 'react'; import { PageProps, navigate } from 'gatsby'; import styled from 'styled-components'; import MainTemplate from '../templates/index'; import { TextInput } from '../components/textInput'; import { Button } from '../components/buttons'; import { API_URLS } from '../utilities'; interface Props extends PageProps { } export default function SignIn({ }: Props): ReactElement { const [state, setState] = useState({ email: ``, password: ``, loading: false }); const { loading } = state; const signInValue = (e) => { setState({ ...state, [e.target.id]: e.target.value }); }; const onSubmit = async (e) => { e.preventDefault(); console.log(state); // 正确设置loading状态:展开原state后覆盖loading属性 setState({ ...state, loading: true }); // 前端校验账号密码是否匹配预期值 const isCredentialsValid = state.email === 'alak@gmail.com' && state.password === 'test123'; try { // 发送请求到Mock API,修正Body格式 const response = await fetch(`https://run.mocky.io/v3/beec46b8-8536-4cb1-9304-48e96d341461`, { method: `POST`, headers: { Accept: `application/json`, 'Content-Type': `application/json` }, body: JSON.stringify({ email: state.email, password: state.password }) }); // 结合前端校验和接口响应判断登录结果 if (isCredentialsValid && response.ok) { alert(`登录成功`); // 修正未定义变量问题,传递正确的邮箱参数 navigate(`/success`, { state: { email: state.email } }); } else { alert(`登录失败`); } } catch (error) { console.error('登录请求出错:', error); alert(`登录请求失败,请重试`); } finally { // 请求结束后重置loading状态 setState({ ...state, loading: false }); } }; return ( <MainTemplate> <TextInput type="text" value={state.email} onChange={signInValue} id="email" required /> <TextInput type="password" value={state.password} onChange={signInValue} id="password" required /> <Button type="submit" name="action" onClick={onSubmit} disabled={loading} > {loading ? `loading...` : `登录`} </Button> </MainTemplate> ); }
关键修复点说明
- 新增前端校验逻辑:通过
isCredentialsValid直接对比你指定的邮箱和密码,确保只有匹配时才触发成功逻辑,不受Mock接口的限制。 - 修正请求Body格式:用
JSON.stringify将账号密码转换为JSON字符串,符合接口的请求格式要求。 - 修复State更新顺序:将
loading: true放在...state之后,确保loading状态被正确覆盖设置。 - 修复未定义变量:把
email改为state.email,避免运行时报错。 - 增加异常捕获:用
try/catch/finally处理请求异常,确保无论请求成功或失败,loading状态都会被重置。
这样修改后,只有输入正确的邮箱alak@gmail.com和密码test123时,才会提示登录成功并跳转至成功页面,其他情况都会提示登录失败。
内容的提问来源于stack exchange,提问作者user12494839




