본문 바로가기

백/spring boot

스프링부트 112강~

<Spring Security 기능 사용할 준비하기>

로그인 기능을 Spring Security가 처리하게끔 할거라 기존의 LoginController를 지우고, AuthenticationService도 지우고, Controller이름도 바꿔주기

 


<Spring Security 설정하기>

강의에서 언급한 대로 의존성 설치 하니까 오류나서 구글링해서 다시 설치함!

 

pom.xml

 

 

설치 후 실행하면 콘솔창에 위와 같이 password가 뜬다. 

-> but 재시작할때마다 password가 바뀌게 될 것이다.

참고로 id는 user 다.


<사용자 지정 유저와 패스워드 인코더를 이용하여 Spring Security 설정하기>

지정해준대로 말고 우리만의 id과 password로 Spring Security 설정하기

 

1.사용자 이름과 패스워드를 저장하려면 LDAP 또는 DB를 사용해야 함

-> 이 강의에서는 간단하게 InMemory 설정자를 사용할 것 

builder를 이용해 UserDetails 객체를 생성하고 InMemoryUserDetailsManager 클래스를 구축해서 객체를 담아 리턴하기

 

-> 취소선 그어져서 패스워드 인코더를 따로 만들어서 사용해주기

(passwordEncoder)

 

-> Function<String, String> passwordEncoder

: 어떤 input이 들어와도, passwordEncoder()는 그걸 인코딩한 다음 사용자 세부정보를 설정할 것  

 

cf) passwordEncoder란?

-> password를 암호화한다

ex) "pass1"이라는 평문 비밀번호를 $2a$10$kZ.aZODm7JAR7AHkuGlIr.6/6cAzZAN//kVrO 이런식으로 바꿈


Spring Security에서 name을 in28minutes라고 설정해두었으므로 기존 코드에서 하드코딩한 부분 제거하기

-> Spring Security로 부터 로그인 된 사용자의 이름 받아오기

 

WelcomeController

<기존 코드>

<바뀐 코드>

 

1. 인증된 사용자가 있다면 인증 세부 정보 받아온다

2. 이 인증 세부 정보부터 사용자 세부정보 받기

3. 기존의 하드코딩된 "in28minutes"를 getLoggedinUsername 함수 호출하도록 바꾸기

 

TodoController

 

cf) 로그인된 사용자를 model이 아니라 Spring Security로부터 받아오는 게 좋다

-> getLoggedinUsername() 메소드 이용하기

-> 기존의 list-todos 요청을 받는 listAllTodos 컨트롤러에서 사용자가 welcomeController가 아니라 직접 url을 쳐서 list-todos로 들어오는 경우, 아래의 코드가 실행되면 넘어오는 model이 없어 username을 찾을 수 없다. 고로 username을 SpringSecurityConfiguration에 있는 값을 꺼내오게 한다!

 

 

TodoService

 


새로운 사용자 추가하기

 

사용자 관리 : SpringSecurityConfiguration에서 한다

-> "in28minutes"와 "dummy"로 지정되어 있는 부분을 지역변수로 바꿔주기

-> 위 코드에서 Function ~ .build()까지를 refractor에서 extractMethod 클릭후 이름을 createNewUser로 설정해 인라인으로 만들어주기

이러면 createNewUser를 이용하여 간단하게 사용자를 추가할 수 있다

 


SpringBootStarterDataJPA를 추가하고 h2 데이터베이스 연결하기

 

인메모리 데이터베이스인 H2를 사용해 연결하기

1. 의존성 추가하기

-> JPA 이용해 데이터베이스와 연결해볼 것

실행시키면 콘솔창에 아래와 같이 뜸

 

이때 주소는 재시작할때마다 바뀌므로 application.properties에 고정 주소 설정해주기

 

다시실행시키면 아래와 같이 데이터베이스가 jdbc:h2:mem:testdb 에 제공된 것으로 바뀌었음을 확인할 수 있다

 

connect 누르면 연결됨

 

but Spring Security때문에 오류 l페이지 나타남!

-> 해결하기 위해 Spring Security 설정 필요


H2 콘솔을 사용하기 위해 Spring Security 설정하기

 

우리가 SpringSecurityConfiguration에 아무 설정도 하지 않는다면

 1. 어느 URL을 들어가든 로그인 URL로 리다이렉트 된다 (모든 URL이 보호된다)

 2. 승인되지 않은 요청에 대해서는 로그인 양식이 표시된다

-> H2에 접속하려면 CSRF설정(사이트간 요청 위조)을 비활성화 + frame 허용해주어야 한다

 

웹 요청이 들어오면 언제나 Security Filter Chain이 제일 먼저 그걸 처리하게 된다

-> 따라서 위의 문제를 해결하기 위해 얘한테 4 가지 설정해주기

  1) 모든 요청을 승인해주기

  2) 모든 URL 보호하기

  3) csrf 비활성화하기

  4) frame 사용할 수 있게 해주기

 -> 1,2는 기본적으로 제공

 

 


Todo 엔티티를 만들고 Todo 데이터를 H2에 채워넣기

 

JPA를 사용하면 Bean을 데이터베이스에 연결할 수 있다

-> @Entity 사용하기

   -> Bean이 데이터베이스 테이블에 매핑된다

 

스프링 부트는

 1) pom.xml에서 h2 데이터베이스를 발견하면 

 2) 사전 설정 시작

 3) 사전 설정 중 @Entity가 발견되면 자동으로 H2 테이블을 생성하기 시작한다

-> 즉 모든 @Entity붙은 애들에 대해 테이블을 생성한다

  -> @Entity에 name 설정안하면 class이름이 테이블 이름으로 설정

@Id : 기본키(Primary Key)임을 나타냄

@GeneratedValue :식별자 값을 자동 생성 시켜줌 (식별자로 사용될 값을 일일이 수동으로 넣어줄 필요 x)

 

<시작데이터 채워넣기>

-> data.sql 파일 생성해 채워넣기 (작은 따옴표만 사용가능!, 큰 따옴표 불가)

 

 But, data.sql은 스프링이 @Entity를 찾아 테이블 생성하기 전에 실행됨!!!

  -> application.properties

JPA 엔티티 매니저가 완전히 초기화된 후에 초기 데이터 로딩 같은 작업을 수행하도록 하기

( JPA를 사용할 때 데이터 소스의 초기화를 지연시키는 작업)

 

 

데이터를 더 추가해주기

 

cf) H2도 인메모리 데이터베이스이기에 어플리케이션을 재시작하면 H2의 모든 데이터는 사라진다!


데이터베이스에서 오는 TodoList 표시하기

 

Todo 추가, 삭제, 검색

-> 스프링 데이터 JPA에서 repository를 사용해 작업

(레포지토리를 사용해 엔티티에 대한 작업 수행)

 

1. Repository 만들기

-> 인터페이스 extends JpaRepository <관리하는 빈, 해당 빈의 id 타입>

 

2. 기존의 TodoController.java를 복사해 TodoControllerJpa.java 만들기

-> 중복된 URL 매핑땜에 오류 나므로 TodoController에서 @Controller는 주석처리 해주기

-> TodoRepository와 대화하려 하므로 TodoService나 정적리스트와 대화 x

 

id로 검색하는 건 바로 검색되는데 필드(ex username)으로 검색하는 건 직접 제공되지 않는다

-> TodoRepository에 내가 직접 작성해줘야 한다

-> username은 Todo빈에 있는 속성이라 스프링데이터JPA는 username으로 검색하기 위한 메소드를 자동으로 제공해준다

-> Repository이용해 찾도록 코드 바꿔주기


추가, 수정, 삭제 기능을 h2 데이터베이스와 연결하기

-> 기존에 todoService가 하게끔 했던 것들을 todoRepository가 하게끔 바꿔주기

 

<add-todo>

- 기존코드

- Repository 이용하도록 수정한 코드

-> 모든 값을 올바르게 설정해서 todo에 넣고 todoRepository.save(todo);

 

<delete-todo>

 

<update-todo>

- 기존 코드

 

- Repository 이용하도록 수정한 코드

GET : 레포지토리에서 findById(id) -> Optional을 리턴하므로 Optional에서 Todo를 받기 위해 .get()을 써주어야 한다.

POST : save 메소드 사용하기 (업데이트인데 save 메소드!)

 

cf) JPA의 save 메소드

  • id를 전달하지 않을 경우 Insert 수행
  • id를 전달할 경우 해당 id에 대한 데이터가 있다면 Update 수행
  • id를 전달할 경우 해당 id에 대한 데이터가 없다면 Insert 수행

마지막으로 TodoService 정의하고 의존성 주입한 부분 지워주기!

 

application.properties에서 spring.jpa.show-sql=true 설정하면 생성되고 있는 모든 쿼리를 볼 수 있다


 

MySQL을 Docker 컨테이너로서 실행하고 우리 어플리케이션에서 MySQL 데이터베이스에 연결하는 방식!

 

Docker를 이용해  MySQL 실행하기

-> cmd 관리자 권한으로 실행 후

docker run --detach --env MYSQL_ROOT_PASSWORD=dummypassword --env MYSQL_USER=todos-user --env MYSQL_PASSWORD=dummytodos --env MYSQL_DATABASE=todos --name mysql --publish 3306:3306 mysql:8-oracle

입력

 

<위 명령어 분석>

docker run --detach --env MYSQL_ROOT_PASSWORD=dummypassword

 --env MYSQL_USER=todos-user
 --env MYSQL_PASSWORD=dummytodos
 --env MYSQL_DATABASE=todos

 --name mysql

 --publish 3306:3306
 mysql:8-oracle

-> 데이터베이스의 루트패스워드, 유저, 패스워드 설정

-> 데이터베이스 생성

-> 컨테이너에 mysql이라는 이름 지정하고 이를 특정한 포트(3306)에 게시

 

정리) 개발용 컴퓨터에 뭔가 설치하려고 할 때 Docker를 많이 사용한다

-> 그걸 사용하기 시작하면 즉시 컨테이너를 삭제할 수 있어서

 


1. pom.xml에 mysql 사용할 수 있도록 mysql 의존성 설치하기

<dependency>
	<groupId>com.mysql</groupId>
	<artifactId>mysql-connector-j</artifactId>		
</dependency>

 

2. application.properties에 datasource.url을 mysql로 바꿔주기

-> spring.datasource.url=jdbc:mysql://localhost:포트번호/데이터베이스이름

-> spring.jpa.hibernate.ddl-auto=update    : 테이블 생성을 위한 프로퍼티

  : 인메모리 데이터베이스를 쓰면 스프링부트가 자동으로 테이블을 만들어주지만 mySQL 같은 실제 데이터베이스를 사용  하면 스프링부트가 대신 테이블을 생성해주지 않는다

  -> 스프링부트가 테이블을 생성해주길 바란다면 프로퍼티를 설정해야 한다

 

https://github.com/in28minutes/master-spring-and-spring-boot/blob/main/11-web-application/99-step-by-step-changes.md

 

master-spring-and-spring-boot/11-web-application/99-step-by-step-changes.md at main · in28minutes/master-spring-and-spring-boot

Spring and Spring Boot Tutorial For Absolute Beginners - 10-in-1 - Spring to Spring Boot to REST API to Full Stack to Containers to Cloud - in28minutes/master-spring-and-spring-boot

github.com

-> 여기서 명령어 긁어올 수 있다

 

 

Docker Desktop에 들어가서 Actions에서 start 눌러주고나서 appication 실행시켜야 돌아간다!