ABOUT ME

쓰고싶을때만

Today
Yesterday
Total
  • [Node.js] JWT 로그인 상태 관리하기 (express , react)
    Login & Sign up/JWT 2022. 3. 24. 21:53
    728x90

     

    [Node.js] JWT 로그인 상태 관리하기 (express , react) 

    jwt를 사용해서 로그인이 되어있으면 "안녕하세요"를 띄워주고 로그인이 되어있지않으면

    로그인 폼을 띄워주도록하겠습니다.

     

     

     

     

    GitHub - auth0/node-jsonwebtoken: JsonWebToken implementation for node.js http://self-issued.info/docs/draft-ietf-oauth-json-web

    JsonWebToken implementation for node.js http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html - GitHub - auth0/node-jsonwebtoken: JsonWebToken implementation for node.js http://self-iss...

    github.com

     

    토큰 생성

    토큰을 생성하기 전엔 key를 지정해줘야합니다

    그냥 아무렇게나 했는데 중요한건 JWT는 key값만있으면 decode를 할수있기때문에 중요한정보는 jwt에 담으면 안됨

    x

    jwt에 집중하기위해서 로그인은 하드코딩해뒀습니다.

     

    jwt.sign으로 토큰을 생성할수있습니다 첫번쨰 인자로 오브젝트를 넘겨주는데

    오브젝트 명으로 토큰을 Decode할 수 있습니다.

     

     

    토큰이 유효한지 검사하기

     body-parser로 토큰을 받아오고 jwt.verify로 토큰이 유효한지

    검사합니다 유효하다면 username(ID)를 토큰에서 decode해서 인사를해줍니다.


    Postman으로 테스트해보기

    구현하기전에 일단 postman으로 제대로 동작하는지 확인해보겠습니다.

    토큰이 제대로 발급되는모습입니다


    아무말이나쓰니까 아무것도 보내주지않죠 이제 토큰을 보내봅시다

    토큰을 끼워보내니 제대로 응답을해주죠 


    react,Axios로 토큰 요청하기

     

      async Submit(ID, PWD) => {
        const Response = await axios({
          method: "POST",
          url: "http://localhost:8080/login",
          data: `ID=${ID}&PWD=${PWD}`,
        });
    
        if (Response.data === "") {
          alert("다시 로그인해주세요");
        } else {
          alert("로그인 성공!!");
          document.cookie = `token=${Response.data}`;
        }
      };

    단순한 로그인함수인데 맨 아래 보시면 토큰을 받아와서

    토큰을 token쿠키에 저장합니다.

    async CheckState() {
        const token = Cookie.get("token");
    
        const Response = await axios({
          method: "POST",
          url: "http://localhost:8080/Check_State",
          data: `token=${token}`,
        });
        console.log(`Response Answer : ${Response.data}`);
        if (Response.data === "") {
          return true;
        } else {
          return Response.data;
        }
      }

    토큰이 유효하다면 *님 안녕하세요를 반환하고

    유효하지않아서 아무것도 받지못했다면 true를 반환합니다.

     

     


    Form.jsx

    import React, { Component } from "react";
    
    class From extends Component {
      constructor(props) {
        super(props);
        this.Submit = this.props.submit.bind(this);
      }
      state = { id: "", pwd: "" };
      render() {
        if (this.props.LoginState) {
          return (
            <>
              <div>
                ID :
                <input
                  onChange={(e) => {
                    this.setState({ id: e.target.value });
                  }}
                  type="text"
                />
              </div>
              <div>
                Password :
                <input
                  onChange={(e) => {
                    this.setState({ pwd: e.target.value });
                  }}
                  type="text"
                />
              </div>
              <button
                onClick={() => {
                  this.Submit(this.state.id, this.state.pwd);
                }}
              >
                Submit
              </button>
            </>
          );
        } else {
          return (
            <>
              <h1>{this.props.article}</h1>
            </>
          );
        }
      }
    }
    
    export default From;

     

     

    그냥 아이디 비번을 가져와서 Submit함수를 실행하는데

    중요한건 조건부로 컴포넌트르 렌더링합니다.


    App.jsx

    import React, { Component } from "react";
    import "./App.css";
    import Login from "./Login";
    import Form from "./Form";
    
    class App extends Component {
      state = { LoginState: true, article: "" };
      Manager = new Login();
    
      componentDidMount() {
        this.IsLogin();
      }
    
      async IsLogin() {
        const LoginResponse = await this.Manager.CheckState();
        console.log(LoginResponse);
        if (LoginResponse === true) {
          alert("로그인을 해주세요");
          this.setState({ LoginState: true });
        } else {
          this.setState({ LoginState: false });
          this.setState({ article: LoginResponse });
        }
      }
    
      render() {
        return (
          <div className="App">
            <Form
              LoginState={this.state.LoginState}
              article={this.state.article}
              submit={this.Manager.Submit}
            />
          </div>
        );
      }
    }
    
    export default App;

    APP컴포넌트가 렌더링 될때 IsLogin함수를 실행합ㄴ디ㅏ

     

      async IsLogin() {
        const LoginResponse = await this.Manager.CheckState();
        console.log(LoginResponse);
        if (LoginResponse === true) {
          alert("로그인을 해주세요");
          this.setState({ LoginState: true });
        } else {
          this.setState({ LoginState: false });
          this.setState({ article: LoginResponse });
        }
      }

    CheckState()함수의 리턴값을 LoginResponse의 담고

    아까 아무것도 받지못하면(token이 유효하지않을때) True를 리턴하게했죠 그니까 로그인하라고 경고창을 띄워주고

    로그인창을 띄워놓습니다.

     

    하지만 제대로받았으면 로그인창을 없애주고 article state를 CheckState의 리턴값(인사말)로 바꿔줍니다

     

     

     

    결과

     

    728x90
Designed by Tistory.