Programming/SpringBoot

Spring Boot 6강 - 로그인, 회원가입

상맹 2021. 9. 19. 00:44
반응형

1. 새 프로젝트 생성

Spring Stater Project

- Lombok : 생성자, Getter / Setter 생성 ( 플러그인도 설치 )

* 라이브러리만 설치 시 컴파일 시 인식이 안됨.( JVM 실행 시)

- MariaDB Driver : Java와 DBMS가 통신할 때 프로토콜 정의

- Spring Boot DevTools : project 저장 시 server 재실행

- Spring Data JPA : jsp를 사용하기 위해 사용

- Spring Web : url로 작업되는 프로젝트를 uri로 변경 => MVC pattern

properies → yml 변경

server:
  port: 8080

spring:
  mvc:
    view:
      prefix: /WEB-INF/views/
      suffix: .jsp
 
  datasource:
    driver-class-name: org.mariadb.jdbc.Driver
    username: cos
    password: cos1234
    url: jdbc:mariadb://localhost:3306/cosdb?serverTimezone=Asia/Seoul
    
  jpa:
    hibernate:
      ddl-auto: none  # create, none
      naming:
    show-sql: true

application.yml 코드 → 이해만 하기

 

2. jsp 활용하여 view 만들기

src/main 폴더 안에 webapp/WEP_INF/views/ 형태로 만들어준다. 경로를 application.yml에 prefix로 설정했다.

layout으로 footer 와 header만들었는데 w3schools 사이트에 bootstrap을 활용하여 만들었다.

 

Bootstrap 4 Tutorial

W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.

www.w3schools.com

<Header>

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="en">
<head>
  <title>Blog</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</head>
<body>

<!-- 네브바 시작 -->
<nav class="navbar navbar-expand-sm bg-primary navbar-light">
 <a class="navbar-brand" href="#">HOME</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
    <span class="navbar-toggler-icon"></span>
  </button>
  <div class="collapse navbar-collapse" id="collapsibleNavbar">
    <ul class="navbar-nav">
      <c:choose>
      <c:when test="${sessionScope.principal.username == null }">
      <li class="nav-item">
        <a class="nav-link" href="/loginForm">로그인</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="/joinForm">회원가입</a>
      </li>
      </c:when>
      <c:otherwise>
      <li class="nav-item">
        <a class="nav-link" href="#">글쓰기</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="/updateForm">회원정보</a>
      </li>  
      <li class="nav-item">
        <a class="nav-link" href="/logout">로그아웃</a>
      </li>  
      </c:otherwise>
      </c:choose>
    </ul>
  </div>  
</nav>
<br>
<!--네브바 끝  -->

- Navbar에서 로그인 시 메뉴가 변경될 수 있도록 jstl를 사용

- spring 에서 jstl 사용법

 

https://mvnrepository.com/artifact/javax.servlet/jstl/1.2

pom.xml에 dependcy 추가

<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>

<pom.xml>

	<dependencies>
		
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.mariadb.jdbc</groupId>
			<artifactId>mariadb-java-client</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		
		<!-- src/main/webapp/WEB-INF/views -->
		<!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-jasper -->
		<dependency>
			<groupId>org.apache.tomcat</groupId>
			<artifactId>tomcat-jasper</artifactId>
			<version>9.0.52</version>
		</dependency>
		
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>

- pom.xml 에 정확히 입력하여도 오류가 발생할 경우 jar 파일을 다운 받아 WEB-INF 폴더 안에 lib 폴더를 만들어 복사하여 넣고, build path를 이용하여 직접 add 하면 사용가능 하다.

 

로그인 전 / 후

- style 태그를 이용해 footer가 페이지 하단에 고정되도록 하였다.

<Footer>

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
    <br>
<div class="jumbotron text-center" style="margin-bottom:0"id="footer">
  <p>🎃🎃🎃상맹의명상🎃🎃🎃</p>
  <p>📞📞📞 010-XXX-7777 📞📞📞</p>
  <p>🌴🌴🌴 부산광역시 XXX XXX 🌴🌴🌴</p>
  <p>🎇🎇🎇 사업자등록번호: 1112-XXX-XXX 🎇🎇🎇</p>
</div>

</body>
</html>

 

<loginForm>

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%@ include file="../layout/header.jsp" %>

	<div class="container">
	<form action="/login" method="post">
	  <div class="form-group">
	    <input type="text" name="username" value="${cookie.username.value }" class="form-control" placeholder="Enter username"  required="required">
	  </div>
	  <div class="form-group">
	    <input type="password" name="password" value="${cookie.password.value }" class="form-control" placeholder="Enter password" required="required">
	  </div>
	   <p><input type="checkbox" name="idChecked"  value="checked" /><label>&nbsp;로그인 정보 저장</label></p>
	  <button type="submit" class="btn btn-primary">로그인</button>
	</form>
	</div>

<%@ include file="../layout/footer.jsp" %>

- 로그인 시 로그인 정보 저장 체크박스를 만들어 이를 체크 할 시 로그인 정보를 쿠키에 저장하고 재로그인 시 정해놓은 시간만큼 쿠키를 유지하여 아이디와 비밀번호가 입력된 상태의 페이지가 나타난다.

- placeholder : 입력 전 안내문구(음영처리)

- required : 필수입력

<joinForm>

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="../layout/header.jsp" %>

	<div class="container">
	<form action="/signup" method="post">
	  <div class="form-group" >
	    <input type="text" name="username" class="form-control" placeholder="Enter username" required="required" >
	  </div>
	  <div class="form-group">
	    <input type="password" name="password" class="form-control" placeholder="Enter password" required="required">
	  </div>
	  <div class="form-group">
	    <input type="email" name="email" class="form-control" placeholder="Enter email address" required="required">
	  </div>
	  <button type="submit" class="btn btn-primary">회원가입</button>
	</form>
	</div>

<%@ include file="../layout/footer.jsp" %>

 

3. 로그인, 회원가입 코드 생성

domain.user 패키지 생성 후 user class 만들기

<User.java>

package com.cos.lsm.domain.user;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
public class User {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private int id;
	private String username;
	private String password;
	private String email;

}

- @AllArgsConstructor → 전체 생성자

- @NoArgsConstructor → 기본 생성자

- @Data → Getter/ Setter 생성

- @Entity → 생성 코드 작성 후 서버실행 시 실행

- @GeneratedValue(strategy = GenerationType.IDENTITY) → 연결할 DB의 자동증가 옵션 : auto-increment

 

- interface 만들기

<UserRepository.java(interface)>

package com.cos.lsm.domain.user;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends JpaRepository<User, Integer>{

	@Query(value = "insert into user (username, password, email) values(:username, :password, :email)", nativeQuery = true)
	void join(String username, String password, String email);
	
	@Query(value = "select * from user where username = :username and password = :password", nativeQuery = true)
	User mLogin(String username, String password);
	
}

 

- Controller 만들기

 

- Dto 만들기

Dto를 통해 받은 것을 의존성 주입(DI)을 하기 위해 Controller에 다음을 추가한다. (로그인, 회원가입) 

추가하는 것의 두가지 방법

 

* 회원가입

① Controller에서 user에 직접 입력

// UserController
@PostMapping("/join")
public String signup(SignupDto dto) {
	User user = new User();
	user.setUsername(username);
	user.setPassword(password);
	user.setEmail(email);
    userRepository.save(user);
    return "redirect:/loginForm";
}

② Controller에서 코드를 줄여 가독성을 높일 수 있다.

// JoinReqDto
@AllArgsConstructor
@NoArgsConstructor
@Data
public class SignupReqDto {
	private String username;
	private String password;
	private String email;
	
	public User toEntity() {
		User user = new User();
		user.setUsername(username);
		user.setPassword(password);
		user.setEmail(email);
		return user;
	}
}
// UserController
@PostMapping("/join")
public String join(JoinReqDto dto) {
	userRepository.save(dto.toEntity());
	return "redirect:/loginForm";
}

* 로그인

// LoginReqDto
@AllArgsConstructor
@NoArgsConstructor
@Data
public class LoginReqDto {
	private String username;
	private String password;
	private String idChecked;
	
	public static void main(String[] args) {
		LoginReqDto dto = new LoginReqDto();
	}
}
// login
@PostMapping("/login")
public String login(LoginReqDto dto, HttpServletResponse response) {
	User principal = userRepository.mLogin(dto.getUsername(),dto.getPassword());
	// principal 인증 주체
	if (principal == null) {
		return "redirect:/loginForm";
	} else {
		if( dto.getIdChecked() == null) {
		session.setAttribute("principal", principal);
		return "redirect:/home";
		} else {
			  session.setAttribute("principal", principal );
			  Cookie cusername = new Cookie("username", dto.getUsername());
			  Cookie cpassword = new Cookie("password", dto.getPassword());
			  cusername.setMaxAge(60*10);
			  cpassword.setMaxAge(60*10);
			  response.addCookie(cusername); 
			  response.addCookie(cpassword);
			  return "redirect:/home";
		}
	}	
}

* 로그아웃

// logout
@GetMapping("/logout")
public String logout() {
	session.invalidate();
	return "redirect:/loginForm";
}

 

4. 결과

<로그인>

<회원가입>

 

반응형