인프런 커뮤니티 질문&답변

hwj9975님의 프로필 이미지
hwj9975

작성한 질문수

[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스

23-01-login / login-success

로그인에 성공해도 name을 불러오지 못 하는거 같습니다

해결된 질문

작성

·

370

0

playgroud 에서 회원을 생성 이후 login 페이지에서 로그인을 성공적으로 하였으나 login success 페이지에서 fetchuserloggedin 이 성공적으로 이루어 지지 않는거 같습니다. 회원가입을 여러번 해서 다른 계정으로 시도해도 name 부분이 표시가 되지 않네요. 혹시 뭐가 문제일까요?

 

20230801_181400.png20230801_181757.png

 

import { useState } from "react";
import { gql, useMutation } from "@apollo/client";
import {
  IMutation,
  IMutationLoginUserArgs,
} from "../../../src/commons/types/generated/types";
import { accessTokenState } from "../../../src/commons/stores";
import { useRecoilState } from "recoil";
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() {
  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 onChangneEmail = (event) => {
    setEmail(event.currentTarget.value);
  };

  const onChangnePassword = (event) => {
    setPassword(event.currentTarget.value);
  };

  const onClickLogin = async () => {
    try {
      //1.로그인 뮤테이션 날려서 accessToken 받아오기
      const result = await loginUser({
        variables: {
          email,
          password,
        },
      });
      const accessToken = result.data?.loginUser.accessToken;
      console.log(accessToken);

      //받아온 accessToken 을 글로벌 스테이트에 저장해야지 모든 애들이 쓸수 있음
      if (accessToken === undefined) {
        alert("로그인에 실패했습니다: 다시 시도해주세요");
        return;
      }

      setAccessToken(accessToken);
      // 3. 로그인 성공 페지이로 이동하기
      void router.push("/section23/23-01-login-success");
    } catch (error) {
      if (error instanceof Error) alert(error.message);
    }
  };

  return (
    <>
      이메일:{" "}
      <input onClick={onChangneEmail} type="text" placeholder="이메일 입력" />
      비밀번호:{" "}
      <input
        onClick={onChangnePassword}
        type="password"
        placeholder="비밀번호 입력"
      />
      <button onClick={onClickLogin}>로그인</button>
    </>
  );
}
import { useQuery, gql } from "@apollo/client";
import type { IQuery } from "../../../src/commons/types/generated/types";

const FETCH_USER_LOGGED_IN = gql`
  query {
    fetchUserLoggedIn {
      email
      name
    }
  }
`;

export default function LoginPage() {
  const { data } =
    useQuery<Pick<IQuery, "fetchUserLoggedIn">>(FETCH_USER_LOGGED_IN);

  return <>{data?.fetchUserLoggedIn.name}님 환영합니다!</>;
}

답변 4

1

hwj9975님의 프로필 이미지
hwj9975
질문자

20230802_162229.png어제 밤에 다시 해보니 딱 한번만 제대로 이름이 표시되고 현재는 다시 안되네요.

 

 

import {
  ApolloClient,
  InMemoryCache,
  ApolloProvider,
  ApolloLink,
} from "@apollo/client";
import { createUploadLink } from "apollo-upload-client";
import { useRecoilState } from "recoil";
import { accessTokenState } from "../stores";

const GLOBAL_STATE = new InMemoryCache();

interface IApolloSettingProps {
  children: JSX.Element;
}

export default function ApolloSetting(props) {
  const [accessToken, setAccessToken] = useRecoilState(accessTokenState);

  const uploadLink = createUploadLink({
    uri: "http://backend-practice.codebootcamp.co.kr/graphql",
    headers: { Authorization: `Bearer ${accessToken}` },
  });

  const client = new ApolloClient({
    link: ApolloLink.from([uploadLink]),

    cache: GLOBAL_STATE,
  });

  // prettier-ignore
  return(
    <ApolloProvider client={client}>
      {props.children}
    </ApolloProvider>
  )
}
노원두님의 프로필 이미지
노원두
지식공유자

네! hwj9975님!

처음에는 됐지만, 2번째 부터 안되셨다고 하셨는데 아무래도 새로고침을 하신 것 같네요!

이후 수업에서 새로고침의 원리와 localStorage 수업이 진행됩니다!

새로고침시 accesstoken이 사라져서 이러한 현상이 발생한 것이며, 해당 수업을 수강하시면 해결 방법을 확인하실 수 있으세요!

0

hwj9975님의 프로필 이미지
hwj9975
질문자

20230804_012637.png20230804_012734.png20230804_012753.png네트워크에서 에러가 뜨지 않습니다. authorization key 도 제대로 전달이 되는거 같은데 왜 이름이 표시가 안되는지 이해가 안가네요....

노원두님의 프로필 이미지
노원두
지식공유자

네! hwj9975님!

코드를 확인해 보니, 최초 올려주신 소스코드현재 결과스크린샷이 다른것 같아요!
최초 올려주신 소스코드는 localStorage를 사용하지 않은 부분이고(router.push도 23-01-login-success로 이동중이에요!), 현재 결과 스크린샷은 localStorage를 사용하신 것 같네요!

따라서, 2가지를 나눠서 답변을 드리자면,
1. 최초 올려주신 소스코드를 기반으로는, 1)오타 또는 2)다이렉트접속, 3)새로고침 등을 체크해 보셔야합니다.
2. 현재 올려주신 localStorage를 사용한 부분은 다이렉트접속과 새로고침에서 토큰이 유지되도록 만드는 방법이 수업에서 진행되므로, 해당 과정을 따라오셨다면 2)다이렉트접속, 3)새로고침 부분은 무시하셔도 되세요.
대신, 이 경우에는 유지되고 있는 토큰(localStorage에 저장된 토큰)이 1시간 만료시간을 넘겼을 경우에는 토큰은 존재하더라도 만료된 토큰이므로 요청에는 실패하게 됩니다!

따라서 현재 결과 스크린샷은 localStorage를 기반으로한 페이지이므로 토큰이 만료되었는지 등을 확인해 주셔야 할 것 같아요!
스크린샷에서 해당 요청의 데이터전송(payload)부분과 응답(response)에서 어떤 결과 또는 에러를 받아왔는지 확인해 보셔야 할 것 같아요!

확인에 어려움이 있으시면 도움을 드릴테니, 위 스크린샷 기준으로 1)http-header부분에 더하여, 2)payload부분3)response부분 총 3개를 함께 올려주세요!

0

hwj9975님의 프로필 이미지
hwj9975
질문자

어제 밤에 다시 한번 시도해 보니까 그 떄 한번 name 부분이 딱 한번 표시되었습니다. 그래서 저는 그떄 아 아침에는 그냥 백엔드 서버가 오류라고 생각을 하고 넘겼지만 오늘 이어서 강의를 들으면 다시 시도해 봤지만 또다시 name 부분이 표시가 안되고 있습니다. 새로고침을 하기 전에도 이름이 표시가 안되고 있습니다.

노원두님의 프로필 이미지
노원두
지식공유자

네! hwj9975님!
아무래도 코드상으로는 크게 문제는 없는 것 같아요!

참고로, 해당 결과페이지의 1.다이렉트 접속시 name이 안나오신다면, 해당 결과페이지에서 2.새로고침을 하셨을시 name이 안나오신다면, 이 2경우는 정상이 맞습니다. 다이렉트 접속도 결국 새로고침과 동일한 원리를 따르기 때문이에요!

이 2경우가 아님에도 불구하고 에러가 계속 발생하신다면,
Network탭의 에러 스크린샷이 있으면 좋을 것 같아요!
해당 쿼리의 http request header 부분과 response 응답 부분이 있으면 좋을 것 같습니다!

 

0

노원두님의 프로필 이미지
노원두
지식공유자

안녕하세요! hwj9975님!

해당 스크린샷에 Network탭의 에러 스크린샷이 있으면 더 좋을 것 같아요!

확인을 해봐야 하겠지만, 아무래도 http header Authorization에 Bearer 방식으로 accesstoken 전달이 제대로 이루어지지 못한듯 싶습니다!

hwj9975님의 프로필 이미지
hwj9975

작성한 질문수

질문하기