OAuth + jwt -> 과제
https://github.com/Moonseonhyeon/springBoot-jwt/commits/master
package들을 만들고
controller > RestApiController
model > User
repository > UserRepository
https://github.com/Moonseonhyeon/springBoot-jwt/commits/master
우리가 security설정을 합니다
SecurityConfig.java만들어요.
<input csrf_token="키값"~~~~>
모든 메서드에 post로 요청으로 test해볼 수 있다.
인터셉터 모든
서버에서
나만(서버) 알고 있는 키값을 정해요 매일매일 다른 걸로 랜덤하게 계속 사용자에게 응답
나에게 요청해서 응답받은 사용자인것을 검증한 것입니다.
http Referral 로 비정상적인 요청 막기 :
curl로 해서 주소 바로 요청한거거나 post로 주소 요청한거면 레퍼럴(Referral)이 없어서 비정상적인 요청을 막을 수 있어요.
하지만 http 레퍼럴로는 부족해요. 강제로 http header에 "http://localhost:8080"
특정
http header
Layer3, 4, 5에 대한 이해가 있어야 크롤링 할 수 있다.
랜덤하게 csrf_token을 날리는 것도 안전하지만 해쉬해서 날리면 더 안전.
cors(Cross-Origin Resource Sharing)
도메인이 다른 비정상적인 자바스크립트 요청을 막는 기본 HTTP 정책
stateful과 stateless
https://studyandlearn.tistory.com/452
jwt는 session필요없다.
stateless로 비활성화 해준다!
Stateful
클라이언트가 요청할때마다 클라이언트의 상태를 유지하는데 이 정보를 서비스 제공에 이용하며
예) 웹서버에서 로그인할때 서버에 세션 객체에 로그인이 되었다고 저장 해둠
서비스를 제공 할때 그 데이터를 사용함.
이 세션은 서버 컴퓨터의 메모리(레디스), 데이터베이스에도 저장 한다.
Stateless (JWT를 사용하는 이유)
상태를 유지하지 않고 클라이언트에서 들어오는 요청으로만 작업을 처리함
이러면 세션을 저장하지 않아도 되고 클라이언트와 서버의 연결고리가 없어서 확장성이 좋다.
현재 배우는 안드로이드에 적합함(모바일에 적합)
안드로이드에는 서버와 주고 받을때 강제로 추가해서 교환하는법이 있긴하지만
JWT를 쓰면 이 번거러움이 해결된다.
세션필요없이 prepare에 내부 저장공간에 토큰을 저장해놓고 사용한다.
인증정보를 다른 어플리케이션으로 전달
ex) OAuth 페이스북/구글/네이버/카카오톡 계정을 이용해서 다른 웹서비스에서도 로그인 가능
Stateful의 문제점
세션
유저가 인증을 할 때 서버는 이 기록을 서버에 저장을 해야한다.
로그인의 유저수가 많아지면 서버의 램이 과부하 되거나 데이터 베이스에 저장할수 있으나
유저의 수가 많으면 성능에 무리를 줄 수 있다.
jwt 중요
STATELESS - session을 유지하지 않아요.
STATEFULL - session을 유지하는거
우리가 하는 인증방식은 암호화가 아니라 서명방식임. 인증과 권한 한꺼번에 하는 서명방식
토큰은 어떤 정보를 담고 있는 어떤 값입니다.
이 토큰으로 인증과 권한을 부여 받을 수 있는 것임.
서버가 토큰을 만들어 준다.
서버가 만들어서 들고 있는 비밀 키를 가지고 있다.
안드로이드라고 생각하고
Login 요청
내가 만든 jwt 인증 필터, jwt 권한 필터를 만들어서 체인에 달거에요.
요청이 서버로 들어오면 무조건 필터에 걸림.
1. 여기서 request.해서 요청한 사람의 정보에 요청 주소를 필터가 낚아채고 request에 http body에 ssar, 1234를 찾음.
DB에서 select하고
2. Detail service
Authentication 객체 만들어지면
3. 토큰 생성(shoulder code) - 인증+권한 만들어져 있는 토큰
토큰을 responce해준다. 응답할 때 바디에 담아서 보내는게 아니라 http Header에 담아온다.
토큰은 어떻게 생겼냐면 -> 토큰은 프로토콜입니다.
header{
Authorization : "Bearer 토큰"
}
안드로이드면
그럼 .getHeader해서 꺼낸 토큰을 shared preparence에 저장.
4. 이 토큰을 Base64로 인코더해서 client에게 던집니다.
프로토콜임. 그럼 너는Base64로 decode해서 쓰면 됨. 프로토콜 이렇게 약속 되어져 있다.
인코딩은 디코딩이 가능. 해쉬는 복호화가 안됨. 차이있다.
서버는
요청이 올 때마다 header에 bearer토큰 꺼내서 내가 만든 토큰(secrete)이 맞는지 (서명)확인
확인되면 ㅣㅏ러ㅣ러이라ㅓㅗ쟏ㅇ랼ㅈ
응답할때 토큰을 넘겨준다.
토큰은 보통 30분 1시간으로 유효시간을 걸어둡니다. 털릴 수 있으니까.
토큰을 훔쳐서 털리면 끝!
https로 만들어야 할 수 도 있다.
토큰은 어떻게 만드냐
User모델에 헷갈리지 않도록 permission, active들을 삭제
config 폴더에 jwt패키지에 JwtAuthenticationFilter를 만든다.
chain중에 UsernamePasswordAuthenticationFilter 를 커스터마이징해서 로그인은 하는데 AuthenticationManager도움을 받아서 Authentication객체를 만들어서 세션에 저장하는데 그러지않고 토큰을 만들어요.
AuthenticationManager는 Ioc되어있다.
https://sjh836.tistory.com/165
SecurityConfig.java
회원가입시에 비밀번호를 bcript암호화 한거를 AuthenticationProvider에게 bcript암호화했다고 알려줄 필요는 없다. 이미 기본값이라서 알고 있다. 그리고 꼭 UserPrincipalDetailsService 꼭 타라고 알려줘야 했었는데
버전이 업그레드되면서 안해줘도 된다.
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter해서 만들었는데
extends
털려도 되거는 유저네임, 권한, .....
안되는거 전화번호, 이메일주소
payload에 클레임들있는데 값에 중요한 내용은 적으면 안됩니다.
토큰을 열어봐요 키값
슈도코드(pseudocode)
지금은 로그인까지...임...
나머지 마지막 필터는 권한처리 필터인데
군한 요청들어오면 header를 읽어서
token읽어서 athentication넣고
서명 검증
제대로 된면 이페이지 보여주고
안되면 안보여주고
https://20200302wc.tistory.com/488?category=897862
'Spring Boot' 카테고리의 다른 글
JSP에서 (0) | 2020.08.11 |
---|---|
jwt 2 (0) | 2020.08.10 |
OAuth 네이버 로그인 (0) | 2020.08.04 |
Optional (0) | 2020.08.04 |
2. Oauth2 구글 로그인 + 페이스북 (0) | 2020.08.04 |