我的身份验证存在此问题,我不知道该如何解决...请帮助!
这是我的Login
组件(来自模式组件):
const Login = () => {
//Context
const { state, setState } = useContext(AppContext);
// Router
const router = useRouter();
// Mutations
const [login, { data }] = useMutation(LOGIN);
const handleMutation = () =>
login({
variables: { email: state.input.email, password: state.input.password },
});
// Effects
useEffect(() => {
if (data) {
Cookies.set("JWT-TOKEN", data.login.accessToken);
setState({
...state,
isAuth: true,
authModal: false, //close login modal
});
router.push("/account");
}
}, [data]);
//CALLBACKS
//email,pass
const handleInput = (e, type) => {
setState({ ...state, input: { ...state.input, [type]: e.target.value } });
};
return (
<div>
<Input onChange={(e) => handleInput(e, "email")} />
<Input type="password" onChange={(e) => handleInput(e, "password")} />
<Button onClick={handleMutation}>Login </Button>
</div>
);
};
这是一个简单的input
,可以将email
和password
存储在全局上下文中(通过反应useContext
)
如果登录突变成功,则从'apollo'收到data
时,我将后端签名的JWT令牌设置在cookie中,然后通过nextJs的router.push()
重定向到/account
页面。
这是全局上下文:
//context object
export const AppContext = createContext();
// provider component
export const AppProvider = ({ children }) => {
const [state, setState] = useState({
showDrawer: false,
showCart: false,
quickSearch: false,
isAuth: Cookies.get("JWT-TOKEN") ? true : false,
authModal: false, // toggle auth modal component
emailToggle: false, //toggle emal auth component
type: "Login", //Login / Sign Up / passReset / setNewPass
input: { name: null, email: null, password: null, passwordConfirm: null },
forgetSent: false, // message after `reset email` sent
});
return (
<AppContext.Provider value={{ state, setState }}>
{children}
</AppContext.Provider>
);
};
这是我的用户Account Page
:
import { useQuery } from "@apollo/client";
import { ME } from "graphql/Query";
const Account = () => {
//Apolo
const { data, loading, error } = useQuery(ME);
const user = data?.me;
// ERROR
if (error) return <div>error: {error.message}</div>;
// LOADING
if (loading) return <p>Loading...</p>;
return (
<span>
Welcome {user?.name} ({user?.email})
</span>
);
};
export default Account;
登录成功后,我被重定向到/account
页,从error
得到apollo
,该查询请求是在没有cookie的情况下完成的。
console.log
useEffect
cookie,那么cookie就在那里。所以问题一定在登录和重定向之间...
这也是我的apollo client
:
import { useMemo } from 'react'
import { ApolloClient, InMemoryCache } from '@apollo/client'
import Cookies from "js-cookie";
let apolloClient
const token = Cookies.get("XSRF-TOKEN");
const enchancedFetch = (url, init) => {
return fetch(url, {
...init,
headers: {
...init.headers,
...(token ? { authorization: `Bearer ${token}` } : {}),
// ...{ authorization: `Bearer ${token}` },
},
}).then((response) => response);
};
function createIsomorphLink() {
const { HttpLink } = require('@apollo/client/link/http')
return new HttpLink({
uri: process.env.NEXT_PUBLIC_GRAPHQL_API_ENDPOINT,
credentials: 'same-origin',
fetch:enchancedFetch
})
}
function createApolloClient() {
return new ApolloClient({
ssrMode: typeof window === 'undefined',
link: createIsomorphLink(),
cache: new InMemoryCache(),
})
}
export function initializeApollo(initialState = null) {
const _apolloClient = apolloClient ?? createApolloClient()
// If your page has Next.js data fetching methods that use Apollo Client, the initial state
// gets hydrated here
if (initialState) {
_apolloClient.cache.restore(initialState)
}
// For SSG and SSR always create a new Apollo Client
if (typeof window === 'undefined') return _apolloClient
// Create the Apollo Client once in the client
if (!apolloClient) apolloClient = _apolloClient
return _apolloClient
}
export function useApollo(initialState) {
const store = useMemo(() => initializeApollo(initialState), [initialState])
return store
}