jusung-c
으 하기싫어
jusung-c
  • 공부 기록 (96)
    • Spring (42)
      • Spring 기초 이론 (8)
      • Spring 핵심 원리 - 기본 (9)
      • Blog 만들기 with SpringBoot (25)
    • JAVA (7)
      • Java 문법 (2)
      • 객체지향의 사실과 오해 (5)
    • Algorithm (47)
      • 자료구조 (3)
      • 완전탐색 (22)
      • 정렬 (4)
      • 이분탐색 (12)
      • 투 포인터 (4)
hELLO · Designed By 정상우.
jusung-c

으 하기싫어

Spring/Blog 만들기 with SpringBoot

전통적인 방식의 로그인

2022. 7. 9. 23:15

1. loginform.js

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

<!-- user 폴더 입장에서는 layout 폴더는 상위폴더인 views로 올라가야 찾을 수 있으므로 다음과 같이 변경  -->
<%@ include file="../layout/header.jsp"%>

<div class="container">

	<!-- 로그인 폼 -->
	<form>
		<div class="form-group">
			<label for="username">Username</label> <input type="text" class="form-control" placeholder="Enter username" id="username">
		</div>

		<div class="form-group">
			<label for="password">Password:</label> <input type="password" class="form-control" placeholder="Enter password" id="password">
		</div>

		<div class="form-group form-check">
			<label class="form-check-label"> <input class="form-check-input" type="checkbox"> Remember me
			</label>
		</div>
	</form>
	<button id="btn-login" class="btn btn-primary">로그인</button>
	
</div>

<script src="/blog/js/user.js"></script>

<!-- user 폴더 입장에서는 layout 폴더는 상위폴더인 views로 올라가야 찾을 수 있으므로 다음과 같이 변경  -->
<%@ include file="../layout/footer.jsp"%>

 

 

2. user.js

let index = {
    init: function() {
		...
        
        $("#btn-login").on("click", () => {  // function(){} 대신 ()=>{} 사용하는 이유는 this를 바인딩하기 위해!
            this.login(); // save함수 이벤트로 호출
        });
    },

    save: function(){
    
        ...
        
    },
    
    login: function(){
        let data = {
			username: $("#username").val(),
			password: $("#password").val()
		};
		
		$.ajax({
			// 회원가입 수행 요청. 
			type: "POST",
			url: "/blog/api/user/login",
			data: JSON.stringify(data), // data는 자바스크립트 객체라서 자바에 던지면 못알아들으니까 JSON으로 변환해주기!
			
			// data는 http body 데이터이다.
			contentType: "application/json; charset=utf-8", // body 데이터가 어떤 타입인지(MIME)
			
			// 요청을 서버로 해서 응답이 왔을 때 기본적으로 String 문자열인데 
			// 만약 생긴게 json이라면 javascript 오브젝트로 변경해준다.
			dataType: "json"
			// 사실 dataType: "json"을 안적어줘도 ajax가 통신을 성공하고 나서 json을 리턴해주면 자동으로 자바 오브젝트로 변환해줌 
			
		}).done(function(resp){
			// 응답의 결과가 성공일 경우 done()
			alert("로그인이 완료되었습니다.");
			// console.log(resp);
			location.href="/blog";
			
		}).fail(function(error){
			// 응답의 결과가 실패일 경우 fail()
			alert(JSON.stringify(error));
		});
    }
    
}

index.init();

 

3. UserApiController.java

@RestController
public class UserApiController {
	
	@Autowired
	private UserService userService; // UserService의 @Service로 Bean에 등록된 상태라서 DI 가능
	
    // session 객체는 스프링 빈으로 등록되어 가지고 있다!! 그냥 함수의 매개변수로 적어줘도 가능하다!
	@Autowired
	private HttpSession session;
    
	@PostMapping("/api/user")
	public ResponseDto<Integer> save(@RequestBody User user) {   // 요청받은 게 Json이니까
		...	
    }
	
	@PostMapping("/api/user/login")
	public ResponseDto<Integer> login(@RequestBody User user) { 
		System.out.println("UserApiController : login 호출");
		
		// 로그인 요청
		User principal = userService.로그인(user); // principal (접근주체)
		
		if(principal != null) {
			// 세션 만들기
			 session.setAttribute("principal", principal);
		}
		
		// 로그인 성공시
		return new ResponseDto<Integer>(HttpStatus.OK.value(), 1);
	}
}

4. UserService.java

@Service
public class UserService {

	@Autowired
	private UserRepository userRepository;
	
	// 회원가입이 하나의 트랜잭션으로 묶이게 된다.
	@Transactional
	public Integer 회원가입(User user) {
		...
	}

	// Select할 때 트랜잭션 시작, 서비스 종료시에 트랜잭션 종료 (정합성 유지)
	@Transactional(readOnly = true)
	public User 로그인(User user) {
		return userRepository.findByUsernameAndPassword(user.getUsername(), user.getPassword());
	}
}

 

5. UserRepository.java

JPA Naming 쿼리 전략

findByUsernameAndPassword 함수는 실제로 JPA가 들고 있는 함수가 아니다.

이름을 이렇게 지어주면 이 함수는 다음과 같이 된다. ?에는 파라미터로 넘겨준 값들이 들어간다.

SELECT * FROM user WHERE username = ? AND password = ?
public interface UserRepository extends JpaRepository<User, Integer>{
	
	// JPA Naming 쿼리 전략
	User findByUsernameAndPassword(String username, String password);
}

 

 

6. header.jsp

jstl 적용

헤더 제일 위에 적용

<%@ taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core" %>
<%@ 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>
	...
</head>
<body>

	...

	<c:choose>
		<!-- 비어있다면  -->
		<c:when test="${empty sessionScope.principal }">
			<ul class="navbar-nav">
				<li class="nav-item"><a class="nav-link" href="/blog/user/loginForm">로그인</a></li>
				<li class="nav-item"><a class="nav-link" href="/blog/user/joinForm">회원가입</a></li>
			</ul>
		</c:when>
		<!-- 비어있지 않으면  -->
		<c:otherwise>
			<ul class="navbar-nav">
				<li class="nav-item"><a class="nav-link" href="/blog/board/writeFrom">글쓰기</a></li>
				<li class="nav-item"><a class="nav-link" href="/blog/user/userForm">회원정보</a></li>
				<li class="nav-item"><a class="nav-link" href="/blog/user/logout">로그아웃</a></li>
			</ul>
		</c:otherwise>
	</c:choose>
			
		</div>
	</nav>
	<br />

 

 

 

전통적인 로그인 방법 성공!!

 

스프링 시큐리티를 이용해서 로그인하게 될 텐데 이땐 지금처럼 컨트롤러에서 @PostMapping해서 하지 않을 것이다.

 

출처 : https://www.youtube.com/c/%EB%A9%94%ED%83%80%EC%BD%94%EB%94%A9

저작자표시 비영리 변경금지 (새창열림)

'Spring > Blog 만들기 with SpringBoot' 카테고리의 다른 글

비밀번호 해쉬 & 시큐리티 로그인  (0) 2022.07.24
스프링부트 Spring Security  (0) 2022.07.14
스프링 JPA의 OSIV 전략  (0) 2022.07.09
DB 격리수준, 스프링의 트랜잭션  (0) 2022.07.09
메인화면 구성  (0) 2022.07.02
    'Spring/Blog 만들기 with SpringBoot' 카테고리의 다른 글
    • 비밀번호 해쉬 & 시큐리티 로그인
    • 스프링부트 Spring Security
    • 스프링 JPA의 OSIV 전략
    • DB 격리수준, 스프링의 트랜잭션
    jusung-c
    jusung-c

    티스토리툴바