728x90
안녕하세요! 😊 이번에는 React/TypeScript와 Spring Boot를 활용한 로그인 기능을 구현한 내용을 공유하려고 합니다.
기본적인 ID/PW 로그인과 함께 세션 저장 및 상태 관리까지 포함된 구조입니다.
1. 프론트엔드 : React/TypeScript 로그인 페이지
📌 로그인 컴포넌트
import React, { useState } from "react";
import "../../styles/account/Login.css";
import { FcGoogle } from "react-icons/fc";
import { SiKakao, SiNaver } from "react-icons/si";
import { Link, useNavigate } from "react-router-dom";
import axios from "axios";
const Login: React.FC = () => {
const navigate = useNavigate();
const [userId, setUserId] = useState<string>("");
const [userPw, setUserPw] = useState<string>("");
const loginButton = async () => {
if (!userId) {
alert("아이디를 입력해주세요.");
} else if (!userPw) {
alert("비밀번호를 입력해주세요.");
} else {
try {
const response = await axios.post("/account/login", { userId, userPw });
if (response.data === "로그인 성공") {
sessionStorage.setItem("userId", userId);
navigate("/home");
} else {
alert("아이디 또는 비밀번호가 일치하지 않습니다.");
}
} catch (error) {
console.error("로그인 요청 중 오류 발생:", error);
alert("서버와의 연결에 문제가 발생했습니다.");
}
}
};
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === "Enter") {
loginButton();
}
};
return (
<div className="loginContainer">
<h1>DangleDangle</h1>
<h2>로그인</h2>
<div className="login-info">
<p>아이디</p>
<input value={userId} onChange={(e) => setUserId(e.target.value)} onKeyDown={handleKeyDown} />
<p>비밀번호</p>
<input type="password" value={userPw} onChange={(e) => setUserPw(e.target.value)} onKeyDown={handleKeyDown} />
</div>
<button className="loginButton" onClick={loginButton}>로그인</button>
<div className="textWrap">
<Link to="/joinAgree">회원가입</Link>
<Link to="/searchAccount">아이디/비밀번호 찾기</Link>
</div>
<div className="snsContainer">
<FcGoogle />
<SiKakao />
<SiNaver />
</div>
</div>
);
};
export default Login;
👉 설명
• axios.post("/account/login", { userId, userPw }) 로 서버에 로그인 요청을 보냅니다.
• 로그인 성공 시, sessionStorage에 userId를 저장하고, navigate("/home")으로 이동합니다.
• handleKeyDown을 활용해 Enter 키로 로그인 가능하도록 구현했습니다.
• 구글, 카카오, 네이버 소셜 로그인 아이콘도 추가했습니다. (아직 연동까지는 구현하지 않았습니다.)
2. 백엔드 : Spring Boot 로그인 API
🛠 Controller : 로그인 요청 처리
• @PostMapping("/login")을 통해 POST 요청을 처리합니다.
• AccountService에서 아이디/비밀번호 검증 후 결과를 반환합니다.
@RestController
@RequestMapping("/account")
public class AccountController {
@Autowired
private AccountService accountService;
@PostMapping("/login")
public String login(@RequestBody AccountVO vo) {
boolean isLoginSuccess = accountService.login(vo);
return isLoginSuccess ? "로그인 성공" : "아이디 또는 비밀번호가 일치하지 않습니다.";
}
}
🔍 Service : 로그인 로직
• accountMapper.checkLogin()을 사용하여 DB에서 유효한 계정인지 확인합니다.
• count > 0이면 로그인 성공, 그렇지 않으면 실패를 반환합니다.
public interface AccountService {
boolean login(AccountVO accountVO); // 로그인
}
@Service
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountMapper accountMapper;
@Override
public boolean login(AccountVO vo) {
int count = accountMapper.checkLogin(vo.getUserId(), vo.getUserPw());
return count > 0;
}
}
🗂️ Mapper : MyBatis 쿼리 작성
USER_ID와 USER_PW가 일치하는 레코드 개수를 조회하여 1 이상이면 로그인 성공으로 처리합니다.
@Mapper
public interface AccountMapper {
int checkLogin(@Param("userId") String userId,
@Param("userPw") String userPw); // 로그인 시 계정 유무 확인
}
<?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="com.project.dangle.account.AccountMapper">
<!-- 로그인 시 계정 유무 확인 -->
<select id="checkLogin" parameterType="map" resultType="int">
SELECT COUNT(*)
FROM USERS
WHERE USER_ID = #{userId} AND USER_PW = #{userPw}
</select>
</mapper>
728x90
'✨ Project > DangleDangle' 카테고리의 다른 글
[ DangleDangle ] 매장 운영시간에 따른 예약 가능 시간대 생성하기 (0) | 2025.04.17 |
---|---|
[ DangleDangle ] 로그인이 필요한 페이지에서 로그인 후 기존 페이지로 이동하기 (useLocation) (0) | 2025.03.28 |
[ DangleDangle ] 로그인 상태 관리 : sessionStorage를 활용한 로그인 처리 (0) | 2025.03.16 |
[ DangleDangle ] PostgreSQL : 기존테이블에서 컬럼을 Auto Increment로 변경하기 (소유자 충돌 트러블슈팅) (0) | 2025.03.07 |
[ DangleDangle ] IntelliJ IDEA + postgreSQL 데이터베이스 연결하기 (0) | 2025.03.04 |