[인증/보안] Sprint - Session - Client

윤후·2022년 3월 24일
1

Section 3

목록 보기
33/41

앞서 손쉽게 server를 만져보았다 이번에도 client에 대해 살펴보자.
sprint를 시작하기에 앞서 어떠한 파일들이 들어있는지 확인해 보자.

Client - App.js

import React, { Component } from 'react';

import Login from './components/Login';
import Mypage from './components/Mypage';

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isLogin: false,
      userData: null,
    };
    this.loginHandler = this.loginHandler.bind(this);
    this.logoutHandler = this.logoutHandler.bind(this);
    this.setUserInfo = this.setUserInfo.bind(this);
  }

  loginHandler() {
    this.setState({
      isLogin: true,
    });
  }

  setUserInfo(object) {
    this.setState({ userData: object });
  }

  logoutHandler() {
    this.setState({
      isLogin: false,
    });
  }

  render() {
    const { isLogin } = this.state;
    return (
      <div className='App'>
        {isLogin ? (
          <Mypage
            logoutHandler={this.logoutHandler}
            userData={this.state.userData}
          />
        ) : (
            <Login
              loginHandler={this.loginHandler}
              setUserInfo={this.setUserInfo}
            />
          )}
      </div>
    );
  }
}

export default App;

위의 코드를 보면 현재, App.js는 class형으로 되어있는 react라는걸 볼 수 있다.

현재 Mypage는 props로 loginHandler함수와 userData state를 내려주고 있고 login에는 login함수와 setUserInfo 함수를 내려주고 있다. 그렇다면 각각의 함수가 무엇의 역할을 하고 있는지 보자.

각각의 함수는 현재 setState로 state를 갱신해주고 있다. loginHandler는 isLogin의 상태를 true로 바꾸어주어 Mypage 컴포넌트를 띄워주는 역할을 하며, logoutHandler는 isLogin의 상태를 false로 바꾸어 주어 Login 컴포넌트 띄워주는 역할을 한다. setUserInfo 함수는 서버에서 데이터를 받아 setState로 userData를 갱신하는 것이다.

그렇다면 다시 왜 해당 함수들이 각각의 컴포넌트로 내려주었는지 생각해볼 수 있을 것이다. Mypage 컴포넌트는 로그인이 된 상태이기 때문에 logout을 구현할 수 있는 logoutHandler함수와 해당 페이지를 구성할 수 있는 setUserInfo함수가 props로 내려가며, Login 컴포넌트는 로그인이 아직 되지 않은 상태이기 때문에 loginHandler를 전해주어 login의 상태를 바꿔주게 되는 것이다.

자, 그럼 각각의 컴포넌트가 어떠한 역할을 해야하는지 대략적으로 정리가 된듯하다. 그렇다면 먼저 Login 컴포넌트를 들여다보자.

Client - components/Login

import React, { Component } from 'react';
import axios from "axios";

class Login extends Component {
  constructor(props) {
    super(props);
    this.state = {
      username: '',
      password: '',
    };
    this.inputHandler = this.inputHandler.bind(this);
    this.loginRequestHandler = this.loginRequestHandler.bind(this);
  }

  inputHandler(e) {
    this.setState({ [e.target.name]: e.target.value });
  }

  loginRequestHandler() {
    
  
  }

  render() {
    return (
      <div className='loginContainer'>
        <div className='inputField'>
          <div>Username</div>
          <input
            name='username'
            onChange={(e) => this.inputHandler(e)}
            value={this.state.username}
            type='text'
          />
        </div>
        <div className='inputField'>
          <div>Password</div>
          <input
            name='password'
            onChange={(e) => this.inputHandler(e)}
            value={this.state.password}
            type='password'
          />
        </div>
        <div className='passwordField'>
          <button onClick={this.loginRequestHandler} className='loginBtn'>
            Login
          </button>
        </div>
      </div>
    );
  }
}

export default Login;

username과 password를 입력할 수 있는 input 태그가 있고, 해당 이벤트를 받는 이벤트 함수가 있다. 이값은 setState로 갱신되며 state로 관리되고 있다.

그렇다면 여기서 어떻게 props로 내려받은 함수들을 활용할 수 있을까?

login 창에 Id와 password를 입력하게 되면 각각의 값들은 setState로 갱신될 것이고, 이 값을 서버에 보내서 확인후 데이터를 받아오게 될것이다. 해당 데이터에는 어떤 값이들어있을지 console을 찍어보자. 또한 이 데이터가 잘 받아와지게 된다면, props로 내려받은 loginHandler를 실행하여 isLogin의 상태를 true로 바꿔주면 되겠다.

import React, { Component } from 'react';
import axios from "axios"

loginRequestHandler() {
    const result = axios({
			url : "https://localhost:4000/login",
			method : "post"
			headers : {withcredentials : true},
			data : {
				userId : this.state.username,
				password : this.state.password
			}
		})
  
  }

commend

console.log(result.data)

result

{ data: null, message: 'ok' }

위의 명령어로 데이터를 잘 받아오는걸 볼 수 있겠다. 그렇다면 데이터가 잘 받아왔을 경우에 login이 구현이 되어야 하며 state에 있는 isLogin을 true로 바꾸어주어 Mypage 컴포넌트로 넘어갈 수 있도록 구현하자.

그리고, Mypage 컴포넌트가 userData를 가지고 페이지를 만들어야 하기 때문에 해당 데이터도 받아오도록 하자.

import React, { Component } from 'react';
import axios from "axios"

async loginRequestHandler() {
    const result = await axios({
			url : "https://localhost:4000/users/login",
			method : "post"
			headers : {withcredentials : true},
			data : {
				userId : this.state.username,
				password : this.state.password
			}
		})

		if(result){
			this.props.loginHandler()
			const userInfo = await axios({
				url : "https://localhost:4000/users/userinfo",
				method : "get",
				headers : {withcredentials : true}
			})
		}
  
  }

위와 같이 데이터를 가지고오는 axios를 사용하였다면, console로 userInfo가 잘 들어오고 있는지 확인해 보자.

commend

console.log(userInfo.data)

result

{
	data : { id: 2, userId: 'kimcoding', email: 'kimcoding@authstates.com' },
	message : "ok"
}

값을 잘 받아오는 것을 볼 수 있고, props로 내려받은 함수를 이용해서 해당데이터를 넣어주어 state로 관리되고 있는 userData를 갱신해 주자.

import React, { Component } from 'react';
import axios from "axios"

async loginRequestHandler() {
    const result = await axios({
			url : "https://localhost:4000/users/login",
			method : "post"
			headers : {withcredentials : true},
			data : {
				userId : this.state.username,
				password : this.state.password
			}
		})

		if(result){
			this.props.loginHandler()
			const userInfo = await axios({
				url : "https://localhost:4000/users/userinfo",
				method : "get",
				headers : {withcredentials : true}
			})
			this.props.setUserInfo(userInfo.data.data)
		}
  
  }

이렇게 코드를 구현하면 Login.js는 구현이 완료되었다. 다음 Mypage.js를 봐보자.

Client - component/Mypage

import React from 'react';
import axios from 'axios';

const FILL_ME_IN = 'FILL_ME_IN';

function Mypage(props) {
  const handleLogout = () => {
  
  };
  return props.userData == null ? (
    <div>Loading...</div>
  ) : (
      <div>
        <div className='mypageContainer'>
          <div>
            <span className='title'>Mypage</span>
            <button className='logoutBtn' onClick={handleLogout}>
              logout
            </button>
          </div>
          <hr />

          <div>
            안녕하세요. <span className='name'>{FILL_ME_IN}</span>! 로그인이 완료되었습니다.
          </div>
          <br />
          <div className='item'>
            나의 유저 네임: {FILL_ME_IN}
          </div>
          <div className='item'>
            나의 이메일 주소: {FILL_ME_IN}
          </div>
        </div>
      </div>
    );
}

export default Mypage;

Mypage컴포넌트를 구성하는 코드를 봐보자. 현재 logout버튼이 있고, 이 버튼을 누르게 되면 handleLogout함수가 실행되게 된다. 그리고 현재 컴포넌트는 App.js에서 props로 state.userData를 받고 있으니, 해당 데이터가 들어갈 곳에 알맞게 넣도록 하자.

import axios from "axios"

function Mypage(props) {
  const handleLogout = async () => {
	  const result = axios({
			url : "https://localhost:4000/users/logout",
			method : "post",
			headers : {withcredentials : true}
		})
  };

위의 결과를 console로 찍어보도록 하자.

commend

console.log(result.data)

result

{ data: null, message: 'ok' }

잘 받아오는걸 확인했으니, logout이 구현되도록 logoutHandler 함수를 작동시키고 stata의 상태를 바꿔주도록하자. 또한 login시에 받은 데이터를 return에 데이더를 넣어주도록 하자.

import axios from "axios"

function Mypage(props) {
  const handleLogout = async () => {
	  const result = axios({
			url : "https://localhost:4000/users/logout",
			method : "post",
			headers : {withcredentials : true}
		})
		this.props.logoutHandler()
  };

return props.userData == null ? (
    <div>Loading...</div>
  ) : (
      <div>
        <div className='mypageContainer'>
          <div>
            <span className='title'>Mypage</span>
            <button className='logoutBtn' onClick={handleLogout}>
              logout
            </button>
          </div>
          <hr />

          <div>
            안녕하세요. <span className='name'>{props.userData.userId}</span>! 로그인이 완료되었습니다.
          </div>
          <br />
          <div className='item'>
            나의 유저 네임: {props.userData.userId}
          </div>
          <div className='item'>
            나의 이메일 주소: {props.userData.email}
          </div>
        </div>
      </div>
    );

이렇게 하면, session의 모든 sprint가 완료된다.

profile
궁금한걸 찾아보고 공부해 정리해두는 블로그입니다.

0개의 댓글

관련 채용 정보