Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- AOP
- transaction
- 스프링 핵심 기능
- Thymeleaf
- SpringBoot
- 인프런
- java
- JPQL
- http
- 그리디
- JDBC
- 스프링
- pointcut
- 스프링 핵심 원리
- 자바
- Android
- 김영한
- 백준
- Proxy
- Exception
- Servlet
- Greedy
- kotlin
- Spring Boot
- db
- springdatajpa
- 알고리즘
- spring
- QueryDSL
- jpa
Archives
- Today
- Total
개발자되기 프로젝트
로그인 처리 본문
로그인 시 검증 처리를 위해 의존성 추가.
implementation 'org.springframework.boot:spring-boot-starter-validation'
- 로그인을 벌써 구현하는 이유?
- 세션에서 로그인 회원 정보를 가져와서, 글 작성시 작성자로 활용하기 위함
1. 로그인 방식
- 쿠키
- 세션
2. loginForm
- 로그인 시 입력할 정보이다.
@Getter
@AllArgsConstructor
public class LoginForm {
private String loginId;
private String password;
}
3. loginService
- 로그인 처리 로직은 간단하다
- 비밀번호가 DB에 입력된 값과 동일하면 Member정보를 반환한다.
- 이 때 DTO로 변환하여 return.
@Service
@RequiredArgsConstructor
public class LoginService {
private final MemberService memberService;
public MemberDto login(String userId, String password){
Member findMember = memberService.findMemberByUserId(userId);
if(!findMember.getPassword().equals(password)){
return null;
}
return findMember.memberToDto(findMember);
}
}
4. SessionManager
- 쿠키를 브라우저에 저장하지 않고 서버에 저장함.
- 세션을 생성, 조회, 만료할 수 있는 SessionManager가 필요함.
- @Component로 스프링 빈으로 등록한다.
- 세션의 저장은 UUID, Value(저장할 객체 여기서는 로그인 회원)을 key & value로 Map에 저장.
- 동시성 문제로 ConcurrentHashMap사용.
- Session Cookie name은 별도인터페이스에서 지정했음. 공용으로 사용.
/**
* 세션 관리
*/
@Component
public class SessionManager {
public static final String SESSION_COOKIE_NAME = "mySessionId";
private Map<String, Object> sessionStore = new ConcurrentHashMap<>();
/**
* 세션 생성
*/
public void createSession(Object value, HttpServletResponse response){
String sessionId = UUID.randomUUID().toString();
sessionStore.put(sessionId, value);
Cookie mySessionCookie = new Cookie(SESSION_COOKIE_NAME, sessionId);
response.addCookie(mySessionCookie);
}
/**
* 세션 조회
*/
public Object getSession(HttpServletRequest request){
Cookie sessionCookie = findCookie(request, SESSION_COOKIE_NAME);
if(sessionCookie == null){
return null;
}
return sessionStore.get(sessionCookie.getValue());
}
/**
* 세션 만료
*/
public void expire(HttpServletRequest request){
Cookie sessionCookie = findCookie(request, SESSION_COOKIE_NAME);
if(sessionCookie != null){
sessionStore.remove(sessionCookie.getValue());
}
}
public Cookie findCookie(HttpServletRequest request, String cookieName){
Cookie[] cookies = request.getCookies();
if(cookies == null){
return null;
}
return Arrays.stream(cookies)
.filter(cookie -> cookie.getName().equals(cookieName))
.findAny()
.orElse(null);
}
}
5. LoginController
- 전반적인 login의 흐름을 control
- @Validated를 사용하면 @ModelAttribute에 바인딩되는 타입이 맞는지 검증됨.
- BindingResult는 @ModelAttribute에 바인딩되는 파라미터의 바인딩 결과를 가지고 있음.
@Slf4j
@Controller
@RequiredArgsConstructor
public class LoginController {
private final LoginService loginService;
private final SessionManager sessionManager;
@GetMapping("/login")
public String loginForm(@ModelAttribute("loginForm") LoginForm form){
return "login/loginForm";
}
@PostMapping("/login")
public String login(@Validated @ModelAttribute("loginForm") LoginForm form,
BindingResult bindingResult, HttpServletResponse response){
if(bindingResult.hasErrors()){
return "login/loginForm";
}
MemberDto loginMember = loginService.login(form.getLoginId(), form.getPassword());
if(loginMember == null){
bindingResult.reject("loginFail", "id또는 pw정보가 맞지 않습니다.");
return "login/loginForm";
}
//로그인 성공
//세션으로 쿠키 처리.
sessionManager.createSession(loginMember, response);
return "redirect:/";
}
@PostMapping("/logout")
public String logout(HttpServletRequest request){
//세션이 없으면 null 반환
HttpSession session = request.getSession(false);
if(session!=null){
session.invalidate();
}
return "redirect:/";
}
}
6. 개발하며 발생한 문제점.
글을 작성하면 title, content가 서버로 넘어오지 않았다.
글을 작성하는 form은 분명히 볼 수 있으나 입력 후 데이터가 바인딩 되지 않음.
원인을 찾다가 글 작성하는 form 보여주는 html파일 명과 return 에 적은 파일명이 달랐다.
- 파일명 : addform.html
- return "post/addForm"
~/post/new/form 접속시 파일명이 다르기 때문에 해당 페이지를 볼 수 없었으면 금방 찾았을 것 같은데..
페이지는 보이나 값이 안보여서 원인을 찾는데 오래 걸렸다.
처음에는 @ModelAttribute 오류인가, HTML의 form에서 문제가 있나...찾다가 한참걸림 ㅜ
아래와 같이 수정하고 나서는 정삭적으로 작동한다.
@GetMapping("/new/form")
public String postForm(Model model, HttpServletRequest request) {
MemberDto memberDto = (MemberDto) sessionManager.getSession(request);
PostDto postDto = new PostDto();
//postDto.setTitle("TitleTest");
model.addAttribute("member", memberDto);
model.addAttribute("post", postDto);
return "post/addform";
}
- 그런데 왜 파일명이 일치하지 않았는데 addform.html은 어떻게 찾아간거니..
7. 해야할 일..
logout버튼을 클릭하면 자꾸 GET method로 요청이 간다...
<button class="w-100 btn btn-dark btn-lg"
th:onclick="|location.href='@{/logout}'|" type="submit" formmethod="post">
로그아웃
</button>
2021-10-04 23:32:03.354 WARN 25348 --- [nio-8080-exec-5] .w.s.m.s.DefaultHandlerExceptionResolver
: Resolved [org.springframework.web.HttpRequestMethodNotSupportedException
: Request method 'GET' not supported]
8. GitHub : 211004 Login
'Project > 블로그 게시판 만들기' 카테고리의 다른 글
home 버튼 추가 (0) | 2021.10.05 |
---|---|
로그아웃 (0) | 2021.10.05 |
회원가입 개발 (0) | 2021.10.04 |
도메인 모델, 연관관계 (0) | 2021.10.03 |
댓글 도메인 개발 (0) | 2021.10.03 |
Comments