cIonecoder / expedia

Expedia Clone Coding - Portfolio
0 stars 1 forks source link

B2B Authentication / Authorization #3

Open BAEKJungHo opened 2 years ago

BAEKJungHo commented 2 years ago

B2B Authentication/Authorization

B2B-Authentication-Authorization-Version2

shbada commented 2 years ago

정호님~ 정리 잘 해주셔서 이해 잘 되었습니다~!

질문

BAEKJungHo commented 2 years ago

refreshToken 이 redis 에서 제거되는거면, accessToken 만료시 refreshToken 으로 유효성을 체크할때 redis 데이터와의 일치 여부는 체크 안하는건가요?! 3분이 지나면 제거되는 이유가 궁금해요!

RefreshToken 의 등장 배경이, AccessToken 의 만료기간이 긴 상태에서 탈취 당하게 되면 보안상 문제가 있기 때문에 AccessToken 의 만료기간을 짧게 가져가서 보안상의 이점을 누리기 위해서 등장한 것입니다. 따라서 RefreshToken 은 보통 클라이언트 쪽에서도 하나 가지고 있고, Redis 같은 In-memory DB 에서도 관리를 하는데, 클라이언트에서 AccessToken 보다 만료 시간이 긴 RefreshToken 을 탈취 당하게 되면, 해커는 RefreshToken 만료가 되기까지 계속 AccessToken 을 재발급 받을 수 있겠죠 ?ㅎㅎ

사실 3분은 짧긴 한 것 같은데, 3분이라는 정책은 회사마다 얼마든지 바뀔 수 있는 부분이고, 중요한 것은 아래 설명할 내용입니다.

위와 같은 문제점 때문에 로그인할 때, 새로 RefreshToken 을 발급하고, 발급과 동시에 DB 에 저장하는 것이죠. 그리고 재발급시에 클라이언트에서 보낸 RefreshToken 이 DB 에 저장된 것과 동일한지 확인하는 것이고요. 따라서, 다른 환경에서 새로 로그인한 경우에는 기존 로그인 된 상태에서 관리되던 RefreshToken 은 만료기간이 남아있더라도 재사용할 수 없겠죠 ㅎㅎ

따라서, 첫 로그인 후 일정 시간 지나고 혹은 로그아웃 시에 RefreshToken 을 제거하게 되면 해커가 AccessToken 을 재발급할 수 없겠죠 !

refreshToken, accessToken 이 다른 redis 서버에 있는 이유가 궁금해요!

accessToken 은 Redis 에서 관리하진 않습니다. accessToken 은 클라이언트에서만 관리되는 토큰이고요, refreshToken 만 Redis 에 존재합니다.

shbada commented 2 years ago
  1. accessToken 의 만료시간이 10분이라고 가정하고, refreshToken 이 10일정도라고 봤을때 accessToken으로 서버랑 통신하고, 10분이 지나서 accessToken 이 만료되면 클라이언트에서 refreshToken으로 accessToken을 재발급 받는거구, 로그인할때마다 refreshToken 을 갱신해서 해커가 AccessToken을 재발급 할 수 없도록 보호하고, 여기서 이제 10분뒤에(accessToken 만료되어) 재발급 시도할때 refreshToken을 보내는데 이 refreshToken은 redis에서 이미 제거된 후면 redis에 저장되어있는 refreshToken 이라는점은 확인못하고 존재 유무만 판단해서 재발급 해주는건가여?

Redis 의 Refresh Token 존재 유무

  1. 아아 맞네여!! refresh Token 저장용 Redis / 사용자&권한 관련 정보를 저장하기 위한 Redis 이게 구분되서 2개로 관리되는 이유가 궁금해요!
BAEKJungHo commented 2 years ago

refreshToken은 redis에서 이미 제거된 후면 redis에 저장되어있는 refreshToken 이라는점은 확인못하고 존재 유무만 판단해서 재발급 해주는건가여?

존재 유무만 판단해서 재발급해준다면, 해커가 악의적으로 이용할수 있겠죠 ?!, 만약에 RefreshToken 이 유효하지 않다면 재로그인을 하라고 유도해야할 것입니다.

보통 RefreshToken 은 요청응답이 자주 발생하지 않아서 AccessToken 보다는 탈취 당할일이 훨씬 적을 것이고, 클라이언트에서 안전하게 보관한다면 쉽게 탈취 당하진 않겠죠? ㅎㅎ

사용자&권한 관련 정보를 저장하기 위한 Redis 이게 구분되서 2개로 관리되는 이유가 궁금해요!

쉽게 인증 Redis 와 인가(권한) Redis 를 따로 구분하는 것입니다. MSA 의 핵심이 SRP 인데, 그런 관점에서 분리되는게 좋지 않을까 생각합니다. 즉, 서버/DB 가 적절하게 분리된다면 인증 쪽에서 문제가 생기더라도 인가쪽은 건드리지 않아도 되겠죠?

shbada commented 2 years ago

정호님..ㅎ 같은 질문일거같은데,,ㅎㅎ

답변중에

RefreshToken 이 유효하지 않다면

refreshToken 은 서버(redis)에서 관리되지 않는다는거구 refreshToken의 유효성 체크 시점이 accessToken이 만료되었을때 refreshToken 으로 accessToken 재발급 요청할때 --> 이때 refreshToken 의 유효성 체크는 어떤게 체크되는거에여?

BAEKJungHo commented 2 years ago

정호님..ㅎ 같은 질문일거같은데,,ㅎㅎ

답변중에

RefreshToken 이 유효하지 않다면

refreshToken 은 서버(redis)에서 관리되지 않는다는거구 refreshToken의 유효성 체크 시점이 accessToken이 만료되었을때 refreshToken 으로 accessToken 재발급 요청할때 --> 이때 refreshToken 의 유효성 체크는 어떤게 체크되는거에여?

shbada commented 2 years ago

정호님~ 본문 수정한 내용으로 다시 보니까 다 이해 잘됬어요! refreshToken 발급 후 바로 삭제가 아닌 토큰의 만료기간이 지났을때 Redis에서 삭제되는 것으로 알고, 이후 재로그인시 다시 발급되는 내용으로 이해했습니다~

질문

권한이나 유저 정보가 변경될 때마다 redis replica 에 들어있는 정보들을 update 쳐준다고 가정

  • 이 말은, 권한이나 유저 정보가 수정되는 요청이 서버에 올때, 서버에서 DB 처리 후에 redis에 인증했던 유저정보를 UPDATE를 진행하는 건가요? 권한정보에 포함되어있는 정보(email, 권한 등)가 UPDATE가 되면 강제 로그아웃을 해주는 행위보다 redis update 가 더 나은 방법인가요?!
BAEKJungHo commented 2 years ago

이 말은, 권한이나 유저 정보가 수정되는 요청이 서버에 올때, 서버에서 DB 처리 후에 redis에 인증했던 유저정보를 UPDATE를 진행하는 건가요? 권한정보에 포함되어있는 정보(email, 권한 등)가 UPDATE가 되면 강제 로그아웃을 해주는 행위보다 redis update 가 더 나은 방법인가요?!

로그아웃도 필요 없고, 인증했던 유저정보를 UPDATE 쳐주는 것도 아닙니다 :)

Search Using User Token 쪽을 한번 보실게요.

admin 이 객실을 수정하고 싶어서 b2b-service 로 token 을 보내서 요청할 것입니다. 그러면 b2b 서비스에서 AccessToken 을 검증할 것이고, 그 과정에서 뽑아낸 ID 값을 Payload 에 담아서 권한 서버로 요청하면, ID 값을 이용해서 자신의 권한을 뽑아오는 것이죠.

[참고] return UserInformation with Authroity 부분에서 UserInfo 를 안넘겨줄 수도 있습니다. 단순히 권한이 있다 혹은 없다 정도로만 Authorization-service 에서 리턴하게끔 해줄 수도 있습니다.

즉, admin 의 요청마다 발생하기 때문에 유저정보 혹은 권한 정보가 UPDATE 되더라도 사용자에게 재로그인하라고 할 필요가 없는 거죠 ㅎㅎ

권한이나 유저 정보가 수정되는 요청이 서버에 올때, 서버에서 DB 처리 후에 redis에 인증했던 유저정보를 UPDATE ..

그러한 로직을 구현할 수도 있고 혹은, DB 에서 변경이 발생하면 Trigger 같은 형식으로도 구현할 수 있지 않을까 생각합니다 ㅎㅎ