해결된 질문
작성
·
347
0
퀴즈를 해결하려고 해당 코드를 작성했는데 로그인을 하려고 하면 Context creation failed: 토큰 만료라는 400 오류가 뜹니다. (새로 가입해서도 해봤는데 똑같은 오류가 떴습니다.)
또한 useAuth를 사용했는데도 로그인 없이 성공페이지로 바로 접속됩니다. 뭐가 문제일까요?
useAuth
export const useAuth = ():void => {
const router = useRouter()
useEffect(()=>{
if(localStorage.getItem("accessToken")===null){
alert("로그인 ㄱ")
void router.push("/z_quiz/section46/02")
}},[])
}
완료 코드
import { gql, useQuery } from "@apollo/client"
import type { IQuery } from "../../../../src/commons/types/generated/types"
import { useAuth } from "../../../../src/components/commons/hooks/useAuth"
const FETCH_USER_LOGGED_IN = gql`
query {
fetchUserLoggedIn {
email
name
}
}
`
export default function LoginSuccessPage():JSX.Element {
const { data } = useQuery<Pick<IQuery,"fetchUserLoggedIn">>(FETCH_USER_LOGGED_IN)
useAuth()
return <>{data?.fetchUserLoggedIn.name}님 환영합니다.</>
}
로그인 코드
/* eslint-disable @typescript-eslint/no-misused-promises */
import { gql, useMutation } from "@apollo/client"
import { type ChangeEvent, useState } from "react"
import type { IMutation, IMutationLoginUserArgs } from "../../../../src/commons/types/generated/types"
import { useRecoilState } from "recoil"
import { accessTokenState } from "../../../../src/commons/stores"
import { useRouter } from "next/router"
const LOGIN_USER =gql`
mutation loginUser($email:String!, $password:String!){
loginUser(email:$email,password:$password){
accessToken
}
}
`
export default function LoginPage():JSX.Element {
const router = useRouter()
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [loginUser] = useMutation<Pick<IMutation,"loginUser">,IMutationLoginUserArgs>(LOGIN_USER)
const [, setAccessToken] = useRecoilState(accessTokenState)
const onChangeEmail = (event: ChangeEvent<HTMLInputElement>):void => {
setEmail(event.currentTarget.value)
}
const onChangePassword = (event: ChangeEvent<HTMLInputElement>):void => {
setPassword(event.currentTarget.value)
}
const onClickLogin = async ():Promise<void> => {
try {
const result = await loginUser({variables: { email, password }})
const accessToken = result.data?.loginUser.accessToken
if (accessToken=== undefined) {
alert("로그인 실패")
return ;}
setAccessToken(accessToken)
localStorage.setItem("accessToken", accessToken)
void router.push("./success.tsx")
} catch(error) {
if (error instanceof Error ) alert(error.message)
}
}
return (
<>
이메일: <input type="text" onChange={onChangeEmail} />
비밀번호: <input type="password" onChange={onChangePassword} />
<button onClick={onClickLogin}>로그인</button>
</>
)
}
답변 1
0
안녕하세요! 현정님!
"토큰만료"라는 메시지가 발생한 것으로 보아, 현재 localStorage에 accesstoken이 저장되어 있고, 이 accesstoken의 만료 시간 1시간이 이미 지난 것으로 보입니다.
이 accesstoken을 삭제하고, 다시 한 번 로그인 시도해 보세요!^^
네! 현정님!
위에서 말씀드린 방법으로 해결이 되지 않으신다면,
관련된 1)에러스크린샷과 network 탭의 2)HTTP Header, 3)Payload, 4)Response 총 4장을 보여주시면 확인 후 답변 드리도록 하겠습니다!^^
네! 현정님!
올려주신 사진의 마지막장에서 Bearer eyJhb~~~ 되어있는 부분이 accesstoken 입니다! 이 부분의 eyJhb~~~ 부분을 복사하시어 jwt.io(수업에서 진행했던 사이트)에 접속하셔서 exp 만료시간을 확인해 보시면, 만료시간이 지난 것을 확인하실 수 있어요
해결 방법으로는, localstorage에 있는 accesstoken을 삭제해 주시고 다시 로그인하셔서 확인하시면 Bearer 뒷부분의 문자열이 새롭게 바뀐 것을 확인하실 수 있답니다!
이렇게하여 만료시간이 늘어난 토큰으로 다시 시도해 주세요!
Application error: a client-side exception has occurred (see the browser console for more information). 넘어간 페이지에서 해당 문구가 뜹니다.
예전에 만든 모든 gql을 사용해 값을 만들고 조회하는 페이지가 같은 이슈로 인해 작동하지 않습니다.