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 |