blog - 9

Lumi·2021년 8월 19일
0

project

목록 보기
12/16
post-thumbnail

전통적인 방식의 로그인 방법

단순히 받은 값을 if문 또는 find를 통해서 값을 비교하는 것이다.

UserService

  • 받은값의 username과 password를 바로 return해준다.

Controller

  • Controller에서는 값을 받고 Service를 통해서 받은값이 DB에 있는지 확인을 한다.

만약 값이 있다면 if문이 발동을 할것이고 session부여해준다.

굳이 Session을 부여해주지 않아도 되는데 session을 부여할경우 jsp에서도 if효과를 줄수가 있다.

header(jsp if효과 부여)

로그인 되게되면 다시 index로 돌아가게 되는데 그떄 header을 변경할수가 있다.

간략하게 설명을 하자면 principal이 null값이면 로그인 + 회원가입이 보여지며

그렇지 않은경우 즉 null이 아닌경우에는 글쓰기 + 회원정보 + 로그아웃이 보여지게 된다.

user.js

  • 추가적으로 function에 설정을 해주어야 한다.

다른 api의 경로를 설정 및 버튼의 설정은 이전에 설정과 동일하기 떄문에 skip하도록 하겠다.

Spring Security를 이용한 로그인

principal : 현재 user의 object에 바로 접근할수 있게 해준다.
-> 이것을 value를 통해서 mapping해준다.
-> property는 이러한 설정으로 작동하겠다 라는 의미.

  • header가 가장 빨리 작동하기 떄문에 header에 설정해 준다.

이후 if의 조건을 살짝만 바꿔주어서 principal의 권한이 없다면 로그인 +회원가입
있다면 글쓰기+회원정보+로그아웃이 나오게 만들어 준다.

SecurityConfig

  • 위 3개의 어노테이션은 Security를 사용할떄 기본적으로 따라오는 어노테이션이다.

기본적으로 권한이 없어도 접근이 가능한 url을 지정해 주었다.
-> 파일이 읽히지 않기 떄문에 추가적으로 css,js까지 지정해 주었다.

  • csrf를 disable처리하는것은 보안에 문제가 있다.
    -> 하지만 테스트 용이기 떄문에 후에 추가적인 설명을 하도록 하겠다.

BCryptPasswordEncoder : 들어오는 값을 해쉬로 암호화 하여 String으로 반환해주는 역할을 한다.

UserService

이렇게 암호화를 해야 하기 떄문에 값이 Post로 들어올떄 그값을 받아서 암호화를 진행한후 다시 password로 저장을 한뒤 그것을 DB에 저장하는 코드이다.

  • 이렇게 암호화 하면 DB에 암호화된 password가 저장되는것을 볼수가 있다. (실제 회원가입할떄 비밀번호는 1111이였다.)

Csrf, Xss

Xss : js를 공격하는 것

  • 대단하게 단순한 공격으로 사이트를 마비시키는 공격이다.
  • Lucy 필터 등을 사용해서 쉽게 방어할수가 있다.

Csrf : 특정 웹사이트에 대해서 요청을 통해서 정보를 뺴오는것을 말한다.(링크를 클릭하면 개인정보를 볼수있는 그런 것)

  • csrf Token 사용, Referrer 검증, captcha 사용 등으로 방어할수가 있다.
  • disable한 이유는 js를 통해서 회원가입을 하게 되면 csrf토큰이 없기떄문에 disable해야한다.

security에서는 자동으로 csrf토큰이 없다면 요청을 막아버린다.

Spring Security를 이용한 로그인 - 2

SecurityConfig

  • login을 할떄에 login페이지에서의 정보가 security에서 다룰수 있게 해주는 코드이다.
  • 원래는 user.js에서 다루었지만 수정하였다.

Security에서 다루게 되면 UserDetail이라는 타입으로 Security에 저장이 되게 되는데 이 타입으로 처리를 해주어야 값을 비교를 해줄수가 있다.

내용이 어려우니 천천히 설명을 해보겠다.

  • BCryptPasswordEncoder : 해쉬를 이용해서 값을 암호화 해주는 메서드로 password를 암호화할떄 사용할 메서드이다.

  • configure(AuthenticationManagerBuilder auth) : 해쉬로 암호화를 하게 되면 DB에는 암호화된 password, 로그인할떄에는 암호화되지 않은 password가 입력이 되기 떄문에 이 두 값을 비교하여 맞는지 아닌지를 확인해주는 메서드이다.

PrincipalDetail

  • security에서 값을 가로채게 되면 UserDetails타입으로 저장이 되기 떄문에 그곳에서 user의 값을 뺴네오는 작업(class)이다.

주석을 통해서 설명을 모두 하였기 떄문에 skip 하겠다.
-> 코드 자체는 어렵지가 않다.

PrincipalDetailService

  • password 같은 경우에는 configure(AuthenticationManagerBuilder auth)를 통해서 알아서 값을 비교할수가 있지만 username값은 비교를 할수가 없기 떄문에 비교를 해주는 코드를 작성을 해주어야 한다.
  • username의 값을 비교해야하기 떄문에 repository에 메서드를 만들어준뒤 사용하여 username의 값을 비교한다. 그후 PrincipalDetail의 생성자에 User의 값을 들어온 user로 지정해 준다.

글로 설명을 하다보니 설명이 잘되는지 모르겟지만 정리를 한번 해보도록 하겠다.

배경적으로 설명해 보자면 Security에서 로그인처리를 하게 되면 Security내에서 들어오는 user의 값을 자체 저장소에 저장을 하게 되는데 이떄 저장되는 타입이 UserDetail타입이다.

PassWord 같은 경우에는 따로 비교를 해줄 필요가 없다.
-> BCryptPasswordEncoder를 통해서 해쉬화 한 값을 configure(AuthenticationManagerBuilder auth) 메서드를 통해서 비교를 해줄수 있기 떄문에.

하지만 username의 값은 비교를 해줄수 없기 떄문에 PrincipalDetailService, PrincipalDetail 를 만들어서 비교해주는 코드를 작성 해야 한다.

PrincipalDetailService에서 하는 역할은 DB에 저장되어 있는 값을 찾은뒤 그 값을 PrincipalDetail의 생성자에게 보내주는 역할을 한다.

PrincipalDetail는 들어온 user객체를 이용하여 UserDetail에 있는 값을 꺼내온다.
-> user.get을 하는 이유는 내가 필요한것은 user객체이지 UserDetail이 아니기 떄문에 값을 꺼내올떄 user를 이용하는 것이다.

  • 이러한 과정을 통해서 username의 값을 꺼내올수 있게 된다.

그 후
auth.userDetailsService(principalDetailService).passwordEncoder( encodePWD())
= securit에서 지정한 경로로 로그인 요청을 가로챈뒤에 principalDetailService에 있는 username을 비교를 하고 그후 passwordEncoder를 통해서 로그인할떄 사용된 password를 다시 인코딩 하여 비교를 해준다.

이러한 과정을 통해서 Security에서 user의 값을 받아서 로그인을 진행할수 있다.

profile
[기술 블로그가 아닌 하루하루 기록용 블로그]

0개의 댓글