inblog logo
|
programmer

    blog 예제 로그인(statefull)

    [Spring] blog 예제 회원가입, 로그인 까지
    Jan 30, 2024
    blog 예제 로그인(statefull)
    Contents
    기본 세팅회원가입 코드 작성H2 DataBase 사용로그인 코드로그인의 목적 → Statefull 만들기검토사항

    기본 세팅

    코드 가져와서 “화면 초기 세팅 완료” 로 reset해서 시작하기

    application

    application-prod.yml 수정
    notion image
    application-dev.yml 수정
    notion image
    application.yml
    notion image
    notion image
    -prod이면 application-prod.yml으로 실행됨 개발 환경에서는 -dev로 할것

    패키지 구성 변경

    notion image
    전
    notion image
    후

    회원가입 코드 작성

    요청은 url, uri로 받는다
    데이터는 DTO로 받는다.
    UserController - join 추가
    @PostMapping("/join") public String join() { return "redirect:/loginForm"; }
    notion image
    UserRequest 생성, DTO작성
    notion image
    notion image
    UserController - join 에 파라미터를 JoinDTO로 넣어줌

    H2 DataBase 사용

    application-dev.yml 에 h2 DB사용을 위한 코드 작성
    spring: datasource: driver-class-name: org.h2.Driver url: jdbc:h2:mem:test;MODE=MySQL username: sa password: h2: console: enabled: true
    notion image
    http://localhost:8080/h2-console 접속하여 데이터베이스 연결
    DB 화면캡처
    notion image
    notion image
    console url 설정 → url로 접속가능하게 하는 코드
    notion image
    User 클래스 생성, Table 생성 → Java에서 코드로 테이블 생성이 가능
    notion image
    코드
    @Data @Entity @Table(name = "user_tb") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; private String username; private String password; private String email; }
    notion image
    DB화면 캡처
    notion image
     
    @Entity는 application-dev.yml에
    notion image
    Spring 서버가 실행될때 Entity를 찾아 분석하여 create함 - 개발모드에서만 사용할 것
     
    제약조건 설정
    User
    @Data @Entity @Table(name = "user_tb") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; @Column(unique = true) private String username; @Column(length = 60, nullable = false) private String password; private String email; @CreationTimestamp private LocalDateTime createAt; }
    notion image
    application-dev.yml → 코드 추가(Run에서 쿼리 편하게 볼 수있음)
    notion image
    notion image
    notion image
    UserRepository 생성(DAO로 생각)
    notion image
    UserRepository
    @Repository public class UserRepository { private EntityManager em; // 의존성 주입 // 생성자 public UserRepository(EntityManager em) { this.em = em; } public void save(UserRequest.JoinDTO requestDTO){ System.out.println("UserRequest에 save메서드 호출됨"); } }
    의존성 주입
    계속 필요할때 마다 new를 하게되면 메모리가 감당하지 못하기 때문에 DI(Dependency Injection)
    notion image
    UserController 코드 전체
    package shop.mtcoding.blog.user; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @Controller public class UserController { private UserRepository userRepository; public UserController(UserRepository userRepository) { this.userRepository = userRepository; } @PostMapping("/join") public String join(UserRequest.JoinDTO requestDTO) { System.out.println(requestDTO); // 1. 유효성 검사 if(requestDTO.getUsername().length()<3){ return "error/400"; } // 2. Model에 위임하기 userRepository.save(requestDTO); // 3. 응답 return "redirect:/loginForm"; } @GetMapping("/joinForm") public String joinForm() { return "user/joinForm"; } @GetMapping("/loginForm") public String loginForm() { return "user/loginForm"; } @GetMapping("/user/updateForm") public String updateForm() { return "user/updateForm"; } @GetMapping("/logout") public String logout() { return "redirect:/"; } }
    error패키지 만들어서 400이름으로 에러 페이지 하나 만들기
    400
    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <h1>에러 : 잘못된 요청을 했습니다. 400</h1> </body> </html>
    notion image
    쿼리 작성 UserRepository
    save
    @Transactional public void save(UserRequest.JoinDTO requestDTO){ Query query = em.createNativeQuery("insert into user_tb(username,password,email) values(?,?,?)"); query.setParameter(1,requestDTO.getUsername()); query.setParameter(2,requestDTO.getPassword()); query.setParameter(3,requestDTO.getEmail()); query.executeUpdate(); }
    notion image
    위에 어노테이션 붙이면됨
    @Transactional을 안붙이면 쿼리를 전송하지 않는다(insert, delete, update 같은 경우는 데이터베이스를 바꾸는 위험한 쿼리로 인식하기 때문에)
    notion image
    다른 기술(알아서 쿼리를 작성해준다)
    saveV2
    @Transactional public void saveV2(UserRequest.JoinDTO requestDTO){ User user = new User(); user.setUsername(requestDTO.getUsername()); user.setPassword(requestDTO.getPassword()); user.setEmail(requestDTO.getEmail()); em.persist(user); }
    notion image
    현재까지의 코드 실행
    notion image
    notion image
    회원가입 후 DB에 insert된 것을 확인
    notion image

    로그인 코드

    UserController-login코드 작성
    @PostMapping("/login") public String login(UserRequest.LoginDTO requestDTO){ // 1. 유효성 검사 if(requestDTO.getUsername().length()<3){ return "error/400"; } // 2. Model 필요 userRepository.findByUsernameAndPassword(requestDTO); // 3. 응답 return "redirect:/"; }
    notion image
    findByUsernameAndPassword에 Alt+Enter하면 바로 생성됨
    UserRepository
    findByUsernameAndPassword
    public User findByUsernameAndPassword(UserRequest.LoginDTO requestDTO) { Query query = em.createNativeQuery("select * from user_tb where username=? AND password=?", User.class); query.setParameter(1,requestDTO.getUsername()); query.setParameter(1,requestDTO.getPassword()); User user = (User) query.getSingleResult(); return user; }
    notion image
    실행
    회원가입
    notion image
    로그인
    notion image
    로그인 완료
    notion image

    로그인의 목적 → Statefull 만들기

    session 영역에 한번이라도 접근하면 session이 만들어짐
    @RequiredArgsConstructor → final들만 생성자를만들어줌
    notion image
    notion image
    notion image
    session과 Request에 접근할 수 있음
    코드
    mustache: servlet: expose-session-attributes: true expose-request-attributes: true
    notion image
    응답 유저가 null이 아니면, session 만들고, index 페이지로 이동
    코드
    User user = userRepository.findByUsernameAndPassword(requestDTO); if(user == null){ return "error/401"; }else{ session.setAttribute("sessionUser",user); return "redirect:/"; }
    notion image
    401
    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <h1>인증에 실패하였습니다. 401</h1> </body> </html>
    로그인 전에는 회원가입과 로그인만 navbar에 보이도록
    로그인이 완료되면 navbar의 회원가입과 로그인을 안보이게
    layout/header.mustache
    notion image
    notion image
    실행
    회원가입 후 로그인
    notion image
    navbar 구성 달라짐
    notion image
     

    검토사항

    테이블생성시 password의 nullable = false 가 안먹힘 null값이 아니라 공백이 입력되는것으로 확인된다.
    유효성 검사에서 password의 길이를 어느정도 이상으로 하면 상관없을 것이다.
    Share article

    programmer

    RSS·Powered by Inblog