🤍 전 강의 25% 할인 중 🤍

2024년 상반기를 돌아보고 하반기에도 함께 성장해요!
인프런이 준비한 25% 할인 받으러 가기 >>

  • 카테고리

    질문 & 답변
  • 세부 분야

    프론트엔드

  • 해결 여부

    해결됨

section 46 퀴즈 관련 질문입니다

23.08.06 16:37 작성 조회수 289

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을 삭제하고, 다시 한 번 로그인 시도해 보세요!^^

현정님의 프로필

현정

질문자

2023.08.07


Application error: a client-side exception has occurred (see the browser console for more information). 넘어간 페이지에서 해당 문구가 뜹니다.

예전에 만든 모든 gql을 사용해 값을 만들고 조회하는 페이지가 같은 이슈로 인해 작동하지 않습니다.

네! 현정님!

위에서 말씀드린 방법으로 해결이 되지 않으신다면,
관련된 1)에러스크린샷과 network 탭의 2)HTTP Header, 3)Payload, 4)Response 총 4장을 보여주시면 확인 후 답변 드리도록 하겠습니다!^^

현정님의 프로필

현정

질문자

2023.08.09

image에러 사진입니다! 05-09 다이나믹 라우팅 페이지입니다.

네! 현정님!

올려주신 사진의 마지막장에서 Bearer eyJhb~~~ 되어있는 부분이 accesstoken 입니다! 이 부분의 eyJhb~~~ 부분을 복사하시어 jwt.io(수업에서 진행했던 사이트)에 접속하셔서 exp 만료시간을 확인해 보시면, 만료시간이 지난 것을 확인하실 수 있어요

해결 방법으로는, localstorage에 있는 accesstoken을 삭제해 주시고 다시 로그인하셔서 확인하시면 Bearer 뒷부분의 문자열이 새롭게 바뀐 것을 확인하실 수 있답니다!

이렇게하여 만료시간이 늘어난 토큰으로 다시 시도해 주세요!

현정님의 프로필

현정

질문자

2023.08.09

고쳐졌습니다 감사합니다~

채널톡 아이콘