로그인 기능 구현하기 (23.09.12)

·2023년 9월 13일
0

React

목록 보기
7/30
post-thumbnail

💡 로그인 기능


📁 VS Code

🔎 Login.js

import React, { useState, useContext } from 'react';
import { TodoListContext } from './App';

const LoginComponent = () => {

    // 전역변수 Context를 사용
    const { setTodoList, setLoginMember, loginMember } = useContext(TodoListContext);

    const [id, setId] = useState('');
    const [pw, setPw] = useState('');

    const login = () => {
        fetch('/login', {
            method : "POST",
            headers : {
                // 전달되는 데이터 타입
                'Content-Type' : 'application/json',

                // 응답 데이터 타입
                'Accept' : 'application/json'
            },
            body : JSON.stringify({
                id : id,
                pw : pw
            })
        })
        .then(resp => resp.json())
        .then(map => {
            console.log(map);

            // 로그인 실패 시
            if(map.loginMember === null){
                alert('아이디 또는 비밀번호가 일치하지 않습니다.');
                return;
            }

            // 로그인 성공 시
            setLoginMember(map.loginMember);
            setTodoList(map.todoList);
            setId('');
            setPw('');
        })
        .catch(e => console.log(e))

    };

    const logout = () => {
        setLoginMember(null);
    };

    return (
        <div className="login-container">
            <table>
                <tbody>
                    <tr>
                        <th>ID</th>
                        <td>
                            <input type="text" onChange={e => setId(e.target.value)} value={id} />
                        </td>
                    </tr>

                    <tr>
                        <th>PW</th>
                        <td>
                            <input type="password" onChange={e => setPw(e.target.value)} value={pw} />
                        </td>
                        <td>
                            <button onClick={login} >Login</button>
                        </td>
                    </tr>
                </tbody>
            </table>

            {loginMember && (
                <button onClick={logout}>로그아웃</button>
            )}
        </div>        
    );
}

export default LoginComponent;

🔎 App.js

import React, { useState, createContext } from 'react';
import './App.css';

import SignupContainer from './Signup';
import Login from './Login';
import TodoList from './TodoList';

export const TodoListContext = createContext(); // 전역변수 생성

function App() {
  // 회원가입, 로그인, 회원의 Todo List 출력/추가/제거
  const [signupView, setSignupView] = useState(false);

  // 로그인한 회원 정보 저장
  const [loginMember, setLoginMember] = useState(null);

  // 로그인한 회원의 todo-list를 저장
  const [todoList, setTodoList] = useState([]);

  return (
    <TodoListContext.Provider value={ {setTodoList, setLoginMember, loginMember, todoList} }>
      <button onClick={ () => {setSignupView(!signupView)} }>
        { signupView ? ('회원 가입 닫기') : ('회원 가입 열기') }
      </button>

      <div className='signup-wrapper'>
        {/* signupView가 true인 경우에만 회원 가입 컴포넌트 렌더링 */}
        {/* 조건식 && (true인 경우) */}
        {signupView === true && (<SignupContainer/>)}
      </div>

      <h1>Todo List</h1>
      <Login />

    </TodoListContext.Provider>
  );
}

export default App;

📁 Spring

🔎 TodoController.java

...
   @PostMapping("/login")
   public Map<String, Object> login(@RequestBody TodoMember member){ 
      return service.login(member);
   }
...

🔎 TodoService.java

...
   Map<String, Object> login(TodoMember member);
...

🔎 TodoServiceImpl.java

...
   @Override
   public Map<String, Object> login(TodoMember member) {
      
      TodoMember loginMember = dao.login(member);
      
      Map<String, Object> map = new HashMap<>();
      map.put("loginMember", loginMember);

      if(loginMember != null) {
         List<Todo> todoList = dao.selectTodoLst(loginMember.getTodoMemberNo());
         map.put("todoList", todoList);
      }
      
      return map;
   }

...

🔎 TodoDao.java

...
   public TodoMember login(TodoMember member) {
      return sqlSession.selectOne("todoMapper.login", member);
   }
...

🔎 todo-mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="todoMapper">
   <!-- 
      resultMap  
      - SELECT 조회 결과(ResultSet) 컬럼명과
        컬럼 값을 옮겨 담을 DTO의 필드명이 같지 않을 때
        이를 매핑 시켜 SELECT시 자동으로 담기게하는 역할
    
    
       -속성
       type : 연결할 DTO (패키지명 + 클래스명 또는 별칭)
       id : 만들어진 resultMap을 지칭할 식별명(이름)
       
       <id> 태그 : PK 역할 컬럼 - 필드 매핑
       <result> 태그 : <id>제외 나머지
    -->
    
   <resultMap type="TodoMember" id="todoMember_rm">
      <id property="todoMemberNo" column="TODO_MEMBER_NO" />
      <result property="id" column="ID" />
      <result property="pw" column="PW" />
      <result property="name" column="NAME" />
   </resultMap>
   
   <resultMap type="Todo" id="todo_rm">
      <id property="todoNo" column="TODO_NO" />
      <result property="title" column="TITLE" />
      <result property="isDone" column="IS_DONE" />
      <result property="todoMemberNo" column="TODO_MEMBER_NO" />
   </resultMap>
  
...
  
   <select id="login" resultMap="todoMember_rm">
      SELECT * FROM TODO_MEMBER
      WHERE ID = #{id}
      AND PW = #{pw}
   </select>
  
...
  

💻 구현 화면

profile
풀스택 개발자 기록집 📁

0개의 댓글