SpringBoot

OXTV 회원가입/로그인

김윤지. 2025. 5. 26. 21:21

사용자 테이블

CREATE TABLE `users` (
	`id` INT(11) NOT NULL AUTO_INCREMENT,
	`user_id` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_uca1400_ai_ci',
	`user_password` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_uca1400_ai_ci',
	`user_name` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_uca1400_ai_ci',
	`email` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_uca1400_ai_ci',
	PRIMARY KEY (`id`) USING BTREE,
	UNIQUE INDEX `user_id` (`user_id`) USING BTREE,
	UNIQUE INDEX `email` (`email`) USING BTREE
)
COLLATE='utf8mb4_uca1400_ai_ci'
ENGINE=InnoDB
AUTO_INCREMENT=2
;

 

index.jsp (홈화면)

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>OXTV 커뮤니티</title>
</head>
<body>
	<h1>뜨개 OXTV 커뮤니티에 오신 것을 환영합니다</h1>
	<p>여기가 니가 만들 세상의 시작이다.</p>
	<form action="/signup" method="get">
		<button type="submit">회원가입</button>
	</form>


	<%
	Object loginUser = session.getAttribute("loginUser");
	if (loginUser != null) {
	%>
	<%= ((com.oxtv.model.User)loginUser).getUserName() %> 님 환영합니다!

	<a href="/logout"><button>로그아웃</button></a>
	<%
	} else {
	%>
	<a href="/signup"><button>회원가입</button></a>
	<a href="/login"><button>로그인</button></a>
	<%
	}
	%>

</body>
</html>

 

HomeController.java

package com.oxtv.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {
    @GetMapping("/")
    public String home() {
        return "index"; // src/main/webapp/WEB-INF/views/index.jsp 반환
    }
}

 

signup.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<!DOCTYPE html>
<html>
<head>
<title>회원가입</title>
</head>
<body>
	<form action="/signup" method="post">
		<input type="text" name="userId" placeholder="아이디" required /> 
		<input type="password" name="userPassword" placeholder="비밀번호" required /> 
		<input type="text" name="userName" placeholder="이름" required /> 
		<input type="email" name="email" placeholder="이메일" required />
		<button type="submit">회원가입</button>
	</form>
</body>
</html>
 

 

UserController.java

package com.oxtv.controller;

import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

import com.oxtv.model.User;
import com.oxtv.repository.UserRepository;

import org.springframework.ui.Model;
import jakarta.validation.Valid;

@Controller
public class UserController {

    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;

    public UserController(UserRepository userRepository, PasswordEncoder passwordEncoder) {
        this.userRepository = userRepository;
        this.passwordEncoder = passwordEncoder;
    }

    @GetMapping("/signup")
    public String showSignupForm(User user) {
        return "signup"; // signup.html 또는 signup.jsp
    }

    @PostMapping("/signup")
    public String processSignup(@Valid User user, BindingResult result, Model model) {
        if (result.hasErrors()) {
            return "signup";
        }

        // 아이디 중복 체크
        if (userRepository.existsByUserId(user.getUserId())) {
            model.addAttribute("userIdError", "이미 사용중인 아이디입니다.");
            return "signup";
        }

        // 이메일 중복 체크
        if (userRepository.existsByEmail(user.getEmail())) {
            model.addAttribute("emailError", "이미 사용중인 이메일입니다.");
            return "signup";
        }

        // 비밀번호 암호화
        user.setUserPassword(passwordEncoder.encode(user.getUserPassword()));

        userRepository.save(user);

        return "redirect:/login"; // 회원가입 끝나면 로그인 페이지로
    }
}

 

User.java

package com.oxtv.model;

import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Entity
@Table(name = "users")
@Getter @Setter @NoArgsConstructor
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(name = "user_id", unique = true, nullable = false)
    private String userId;

    @Column(name = "user_password", nullable = false)
    private String userPassword;

    @Column(name = "user_name", nullable = false)
    private String userName;

    @Column(unique = true, nullable = false)
    private String email;
}

 

UserRepository

package com.oxtv.repository;

import com.oxtv.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;

public interface UserRepository extends JpaRepository<User, Integer> {
    User findByUserId(String userId);
    boolean existsByEmail(String email);
    boolean existsByUserId(String userId);
}

 

login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<!DOCTYPE html>
<html>
<head>
    <title>로그인</title>
</head>
<body>
    <h2>로그인 페이지</h2>
    <form action="<c:url value='/login' />" method="post">
        <input type="text" name="userId" placeholder="아이디" required />
        <input type="password" name="userPassword" placeholder="비밀번호" required />
        <button type="submit">로그인</button>
    </form>
    
      <c:if test="${not empty errorMessage}">
        <p style="color:red">${errorMessage}</p>
    </c:if>
    
    
    <p>계정이 없으면 <a href="<c:url value='/signup' />">회원가입</a> 하세요.</p>
</body>
</html>

 

LoginController.java

package com.oxtv.controller;

import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.oxtv.repository.UserRepository;
import com.oxtv.model.User;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.ui.Model;

@Controller
public class LoginController {

	@Autowired
	private UserRepository userRepository;

	@Autowired
	private PasswordEncoder passwordEncoder;

	@GetMapping("/login")
	public String loginForm() {
		return "login"; // login.jsp 보여줌
	}

	@PostMapping("/login")
	public String login(@RequestParam String userId, @RequestParam String userPassword, HttpSession session,
			Model model) {
		User user = userRepository.findByUserId(userId);
		if (user == null) {
			model.addAttribute("errorMessage", "아이디가 존재하지 않습니다");
			return "login"; // login.jsp 다시 보여줌
		}

		if (!passwordEncoder.matches(userPassword, user.getUserPassword())) {
			model.addAttribute("errorMessage", "비밀번호가 틀렸습니다");
			return "login";
		}

		session.setAttribute("loginUser", user); // 로그인 세션 생성
		return "redirect:/"; // 로그인 성공하면 메인 페이지로
	}

	@GetMapping("/logout")
	public String logout(HttpSession session) {
		session.invalidate(); // 세션 제거
		return "redirect:/"; // 메인 페이지로 이동
	}

}

 

SecurityConfig.java

package com.oxtv.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.context.annotation.Bean;

@Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.csrf().disable() // CSRF 보호 비활성화 (개발용)
            .authorizeHttpRequests(auth -> auth.anyRequest().permitAll()) // 모든 요청 허용
            .formLogin().disable() // 로그인 폼 비활성화
            .httpBasic().disable(); // 기본 인증 비활성화

        return http.build();
    }
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    } //암호화 비교
}