9:22 학원 도착
<9:30 1교시>
코드를 봤을 때 2의 경우가 출력되어 있는 것은 타임리프에 추가된 sec:authorize 기능이 2번을 출력하라는 조건을 읽어서.
타임리프에 추가된 시큐리티 기능 덕에 sec:authorize를 사용할 수 있다.
웹브라우저 입장에서는 고객이 /study를 요청했는데, /user/required-loginform으로 요청을 다시 하라고 redirect 응답하라는 응답을 받아서 redirect 페이지를 보여줌.
서버의 입장에선 클라이언트가 /study 요청을 해오는데 여기는 authenticate 인증이 되어야 요청이 처리되는 곳이라, 서버에서 요청을 다시하라고 redirect 응답을 주는 것
로그인 하지 않아도 보여줄 경로(페이지)는 whitelist 배열(java의 {}는 배열)에 추가하면 된다.
/study 요청했을 때, /user/required-loginform 을 리다이렉트하는 부분.
이 요청을 처리할 Controller와 template 페이지가 있어야 한다.
Controller 부분
template 부분
/user/login을 요청하면 로그인하고 원래 가려던 페이지로 리다이렉트 됨.
그건 SecurityConfig에서 설정한 내용에서 찾아내서 가능한 것이다.
단어나 표현이 달라져도 양쪽이 일치하면 된다. (login 이 아니라 signin 이런 상황이어도)
방금 전 본거는 강제로 로그인 하러 들어가는 로그인 폼이어서 required-loginform이고
자발적으로 로그인한 사람이 들어가는 로그인 폼은 loginform이라고 되어 있고, 마찬가지로 파라미터 명은 설정된 것과 일치하게만 작성해주면 된다.
강제 로그인 폼은 스프링이 인식해서 화이트리스트로 넣어놓는 거는 당연한거구, 자발적 로그인 폼은 whitelist에 넣어두어야 접근할 수 있다.
리다이렉트 이동 : 웹브라우저가 클라이언트에게 다른 페이지로 이동하라고 주소창을 바꾸면서 해당 주소창으로 이동시키는 것
포워드 이동 : 응답하지 않은 상태에서 서버 내에서 다른 경로로 이동해서 클라이언트가 인식을 못하고 주소창의 변화가 없음
예를 들어, 클라이언트가 A 라는 경로로 요청을 해서 뭔가 요청을 처리하다 보니 B 경로를 타야하면 서버 내에서 클라이언트에게 주소창으로 응답하지 않고 기능만 처리해서 응답함
post 방식으로 전송된 내용에 대해 응답해야 하기 때문에 @PostMapping을 해야지, post 방식으로 전송된 내용을 인식하지 @GetMapping 해버리면 아래 내용이 실행되지 않는다.
강제로 로그인 폼으로 갔다가 오면 원래 가려던 곳으로 보내주는 역할을 해주는 Handler 처리가 필요하다.
AuthSuccess 핸들러로 오면 일련의 과정을 거치고, 포워드 응답 후 리다이렉트 응답이 이루어진다.
<10:30 2교시>
로그아웃 기능 : 순식간에 /user/logout 이 일어난 다음 / ( 최상위 경로) 가 리다이렉트 된다.
지금은 logoutSuccessUrl 을 사용해줬지만 추가적인 로직이 필요하다면 logoutSuccessHandler를 사용해줄 수 있다.
설정 정보를 가지고 있는 httpSecurity의 build 메소드를 호출해서 리턴되는 객체 DefaultSecurityFilterChain을
리턴해주고, 스프링은 이 객체에 관련된 것을 관리해준다.
DefaultSecurityFilterChain은 SecurityFilterChain의 자식이다.
스프링이 로그인 처리를 할 때 loadUserByUserName 메소드 객체를 생성해서 처리를 하기 때문에 DB에서 데이터를 읽어서 처리하는 기능이 가능하다.
UserDetailsService에서 무슨 작업을 하느냐,
사용자가 로그인해서 /user/login을 요청했을 때
스프링 시큐리티가 userName과 password를 직접 추출했을 때
추출한 정보가 맞는 정보인지 확인하는기 위해서 그 정보를 DB에서 대조하는 작업을 loadUserByUsername에 대조해서 UserDetails 객체(DB에 저장된 암호화된 비밀번호, role 정보, 권한 정보 등)를 리턴해주면
이 리턴된 객체를 받아서 스프링 시큐리티가 자기가 추출한 거(입력된 정보)랑 DB에서 얻어온 거(UserDetails객체)랑 비교해서 일치하면 role에 맞는 로그인 처리를 해준다는 것
근데 우리가 아래에서 한 거는 DB를 찾은 게 아니고 임시 데이터를 사용해서 사용자, 관리자, 직원 이렇게 따로 입력했는데.
이부분이 DB에 연동되었을 때의 실제 코드는 다음과 같다고 함.(모바일에서 찍은 사진 올리기)
그러고 나면 SecurityConfig에 있는 AutheticationManager가 비교해주는 데 사용한다.
그러면 어떻게 암호화하느냐, 에 대해서 암호화 하는 부분 초간단하여 암호화 부분 연습해보기
Spring08에다가 연습하느라 기능 추가하고, maven 에서 기능추가한 부분에 대해 프로젝트 업데이트
비밀번호를 암호화해주는 Class BCryptPasswordEncoder를 사용해서 비밀번호 암호화 해주기
암호화는, 암호화를 실행 할 때마다 새로운 암호가 부여된다.
암호화된 비밀번호를 decode 하는 것은 불가능하다.
하지만 메소드를 이용해서 1234로부터 파생된 비밀번호임은 알 수 있다. (메소드가 알아서 해준다)
<11:30 3교시>
관점지향 프로그래밍(aop)를 위한 dependency 추가
관점 지향 프로그래밍
서비스를 우리가 만들텐데, 서비스에서 해당 로직을 처리하는 시간을 알고 싶거나 처리되는데 걸리는 시간을 알고 싶다면 서비스 메소드 시작 시 시간을 기록하고 메소드 끝나기 직전에 시간을 기록해서 두 시간의 차이를 기록하면 됨.
서비스가 겁나 많으면 서비스 실행 시간을 측정하려면 적용할 곳이 많아서 빡친다 번거롭다.(심지어 추가했다가 삭제하라면 더욱!!!)
이렇게 핵심 비즈니스 로직은 아니지만 여러번 필요한 관심사 코딩(횡단관심사)이 있을 때 AOP를 사용하면 설정만으로 원하는 코드를 넣었다가 뺐다가 할 수 있는 기능을 해준다. 마치 직접 코딩한 것처럼 런 타임 시에 동적으로 활용할 수 있다.
AOP를 사용하면 메소드 매개 변수에 전달된 객체를 조사하는 것도 가능해진다.
미리 그 객체를 조사해서 조건을 검사하고 조건을 만족하지 않으면 메소드가 실행되지 않게 작동하게 하는 것도 가능하다.
리턴된 데이터를 조사하는 기능도 있다.
리턴된 데이터에 추가하는 것도 가능하고 조작하는 것도 가능하다.
일단 패키지 만들기로 시작
Aspect 클래스에 코딩을 하는 것만으로 얘가
Util 클래스에 있는 저녀석(WritingUtil)의 안에 있는 메소드들이 실행되기 직전에 자동으로 실행될 수 있게 할 수 있다.
근데 이 녀석을 잘 활용하려면 메소드 이름 작성하는데 머리를 잘 써야 함. 그리고 매개변수를 받을지 여부도 잘 고려해야지, 안그러면 무용지물.
우리가 run 하면 메인 메소드 SpringApplication.run으로 @SpringBootApplication 어노테이션이 붙은 클래스의 객체가 생성되고, 컴포넌트 스캔이 끝나서 빈이 모두 컨테이너에 들어가 있는 상태고 메인 메소드가 실행되면서 객체들이 만들어짐.
@PostConstruct는 SpringJavaApplication 이 클래스로 객체가 생성이 되고 컴포넌트가 스캔된 직후, 그러니까 스프링 프레임워크가 초반 설정을 마쳐서 Ready 된 상태 이후 @PostConstruct가 달린 메소드가 호출됨.
@Aspect와 @Component 가 달린 클래스로 인해 이 클래스의 메소드들이 적용되는 메소드들의 코드에 동적이며 횡적으로 추가되어 변형이 일어난 상태여서 메인 메소드에서 호출할 때 @Before 또는 @After의 적용을 받아 변형되는데,
단, AOP 클래스를 활용하려면 bean인 녀석들에 한해서만 적용이 된다.(당연한 얘기인 것 같다, 왜냐하면 @Autowired 되려면 bean으로서 스프링 빈 컨테이너에서 관리되고 있어야 하니까.)
@Around 기능을 활용하면 얻어온 매개변수도 읽어들 일 수 있다고 함. 그건 다음 시간에 보기로 함.
<12:30 4교시>
이 메소드의 근처(Around)에서 작동하는 AOP를 만들어보겠다.
AOP 패키지에서 특정 단어가 있으면 출력이 안되게 하는 기능을 만들어보려고 함.
Around를 사용하게 되면 ProceedingJoinPoint 를 매개변수로 사용할 수 있음
getArgs()하면 매개변수에 전달된 모든 데이터 타입에 대해 데이터의 목록(Object[] 오브젝트 배열)을 얻어올 수 있음.
즉, 매개변수를 전부 가져올 수 있음
getThis()하면 매개변수가 있는 곳의 참조값을 가져올 수 있음
Aspect로 매개변수의 내용을 추출하는 동안 sendGreeting 메소드가 수행되지 않았다.
제대로 수행하게 하려면 joinPoint.proceed();메소드가 필요하다.
이제 잘 실행됨.
그리고 특정 문구가 있으면 아예 실행되지 않게 하고 싶으면, 그냥 return 해버리면 됨. 개꿀.
'자바풀스택 과정 > 자바 풀 스택 : 수업내용정리' 카테고리의 다른 글
자바 풀 스택 2/24 오전 기록 061-1 (0) | 2025.02.24 |
---|---|
자바 풀 스택 2/21 오후 기록 060-2 (0) | 2025.02.21 |
자바 풀 스택 2/20 오후 기록 059-2 (0) | 2025.02.20 |
자바 풀 스택 2/20 오전 기록 059-1 (0) | 2025.02.20 |
자바 풀 스택 2/19 오후 기록 058-2 (0) | 2025.02.19 |