🔑 인증과 인가: 우아한테크코스 5기 백엔드 후추 발표 요약
==1. 📌 인증과 인가의 개념==
1.1. 🏪 편의점 예시
- ==인증==: 신분증을 통해 ==본인 임을 확인.==
- ==인가==: 신분증 확인 후 주류 구매 ==권한 확인 (미성년자 불가).==
1.2. 💻 애플리케이션 예시 (게시판)
- ==인증==: 계정과 비밀번호로 로그인.
- ==인가==: 게시글 작성/수정/삭제 권한 부여 (본인 글만 가능).
2. 🌐 인증 유지 방법: 세션 vs 토큰
2.1. 📡 HTTP와 Stateless 특징
-
HTTP는 ==무상태성 (Stateless)을 가짐.==
-
서버는 클라이언트의 이전 요청 상태를 ==기억하지 못함==.
sequenceDiagram participant Client participant Server Client->>Server: 인증 요청 (나 후추야!) Server->>Client: 인증 성공 (후추 반가워!) Client->>Server: 글 삭제 요청 (인가 필요) Server->>Client: 누구세요? (인증 정보 없음)
2.2. 🍪 세션 (Session)
-
서버가 클라이언트 상태 정보를 ==서버 내에 저장==.
-
편의점 점원이 얼굴을 기억하는 방식과 유사.
sequenceDiagram participant Client participant Server participant DB Client->>Server: 로그인 요청 (계정/비밀번호) Server->>DB: 인증 확인 DB-->>Server: 인증 결과 Server->>Client: 세션 ID 발급 Client->>Server: 인가 필요한 요청 (세션 ID 포함) Server->>Server: 세션 ID 확인 (기존 기록과 비교) Server->>Client: 인가 완료
2.3. 🔑 토큰 (Token)
- 사용자 인증 정보가 담긴 ==징표==.
- JWT (JSON Web Token) 예시: ==
xxx.yyy.zzz==
2.3.1. JWT 구조
-
==헤더 (Header)==: 토큰 유형, 암호화 알고리즘 정보 (Base64 URL 인코딩).
-
==페이로드 (Payload)==: 사용자 정보, 토큰 정보 (발행 대상, 시간, 만료 시간 등, Base64 URL 인코딩).
-
==시그니처 (Signature)==: 토큰 무결성 보장, 변조 방지. 헤더+페이로드를 암호화 알고리즘과 비밀키로 생성.
sequenceDiagram participant Client participant Server participant DB Client->>Server: 로그인 요청 (계정/비밀번호) Server->>DB: 인증 확인 DB-->>Server: 인증 결과 Server->>Server: 토큰 발행 (비밀키 사용) Server->>Client: 토큰 전달 Client->>Server: 인가 필요한 요청 (토큰 포함) Server->>Server: 토큰 검증 (비밀키 사용, 변조 확인) Server->>Client: 인가 완료
3. ⚖️ 세션 vs 토큰 비교
3.1. 📈 확장성 (Scalability)
-
==세션==: 서버 확장 시 세션 정보 공유 문제 발생, 추가 조치 필요 (불리).
-
==토큰==: 각 서버가 동일한 비밀키로 토큰 검증 가능, 확장 용이 (유리).
graph LR A[Client] --> B(Load Balancer) B --> C{Server 1} B --> D{Server 2} B --> E{Server 3}
3.2. 🛡️ 보안 (Security)
- ==세션==: 세션 ID 탈취 시 서버에서 삭제 가능 (보안 이점).
- ==토큰==: 토큰 탈취 시 서버에서 즉시 막을 방법 부재 (보안 취약).
4. 🤔 결론
4.1. 🔑 인증, 인가 구현 방식 선택 기준
- 확장성, 보안 외 다양한 요소 고려 필요.
- 각 방식의 장단점을 이해하고 상황에 맞는 선택 중요.
대본
반갑습니다 저는 우아한테크코스 5기백엔드 후추입니다인증과 인가에 대해서 발표해 보겠습니다제 발표 목차는 다음과 같습니다첫 번째로 인증과 인가의 개념에 대해 살펴보고요그 다음에 인증을 유지하는 방법세션과 토큰을 보고세션과 토큰을 비교하면서 발표를 마무리 하겠습니다발표 대상은요인증과 인가를 처음 접하는 사람입니다만약에 이 발표가이미 알고 계신 분들은 복습한다는 차원에서발표를 들어주시면 감사하겠습니다자 그럼 인증, 인가란 과연 무엇일까요실생활의 예시를 통해서 한번 살펴보도록 하겠습니다저희가 편의점에 간다고 생각을 해보겠습니다편의점에 갔습니다 매장에 점원이 있겠죠그리고 저희는 계산대로 가서 물건을 내려놓을 겁니다저희가 주류를 산다고 가정을 해봅시다그러면 매장의 점원은 저희한테신분증을 요구를 할 것입니다그럼 저희는 신분증을 점원에게 건네주게 됩니다그럼 점원은 이 신분증을 보고이 고객이 누구인지를 확인하는 과정을 거칩니다이것이 인증입니다인증이란 식별 가능한 정보로사용자가 누구인지 확인하는 절차입니다자 이제 신분증 확인을 하고 나서저희는 주류를 살 수 있게 되었습니다그래서 주류를 사서 갔고요이제 다른 손님이 왔습니다 이 손님은 교복을 입고있어서 마치 학생인 것처럼보이는데요 이 손님도 주류를 산다고 합니다그래서 신분증을 똑같이 제시를 했습니다근데 매장 점원이신분증을 보더니 이 사람한테는술을 팔 수 없다고 했습니다그 이유인 즉슨 이 신분증을 살펴보면2006년생인 것을 확인할 수 있습니다그러니까 이 손님은 자신에게 자신이 누구인지인증 과정을 밟았지만주류에 대한 접근권한이 없는 청소년이기 때문에술을 살 수 없었던 것입니다이것이 인가입니다인가란 인증된 사용자가 특정 자원에 접근할 수 있는지권한을 확인하는 절차입니다이번에는 실생활이 아니라애플리케이션에서 예시를 살펴보겠습니다게시판 서비스라고 생각하시면 됩니다게시판 서비스에 사용자가 있을 거고요사용자가 계정과 비밀번호를 입력해서 로그인을 할 것입니다이것이 인증입니다자 이제 인증을 마친 사용자가 게시글을 추가하거나게시글을 수정하거나 삭제할 수 있을 것입니다하지만 다른 사람이 쓴 글을 수정하거나삭제할 수는 없을 것인데요이것이 인가가 적용이 된 개념입니다네 인가가 적용이 된 개념입니다자 그러면 인증과 인가를 어떻게 구현해 볼 수 있을까요먼저 이 고민을 하기 전에한 가지 알아야 할 사항이 있습니다그것은 클라이언트와 서버가 서로HTTP라고 하는 통신규약에 의거해서요청과 응답을 주고받는다는 것인데요 이 HTTP는Stateless하는 무상태성이라는 특징을 갖습니다이것은 클라이언트의 요청이 서버에 독립적으로 처리되며서버가 클라이언트에 대한 정보를 유지하거나기억하지 않는다는 것을 의미합니다자 그래서 다음과 같은 상황이 벌어질 수 있습니다클라이언트가 서버에게 나 후추야 하고인증 요청을 보냅니다그러면 서버가 후추 반갑다고 인증이 성공한 응답을 보내줍니다근데 클라이언트가 이후에 이제 인증이 되었으니까인가가 필요한 절차인 글 삭제를 요청을 했습니다근데 서버는 이 클라이언트의 이전의 요청에 대한 상태를전혀 관리하고 있지 않기 때문에 이 사용자가 누구인지모르게 됩니다즉 인증이 유지가 되지 않고다시 인증을 해야만 하는 상황이 발생하는 것입니다그럼 저희와 같은 개발자는이 인증을 어떻게 유지할 수 있을 것인가에대해서 고민을 해봐야겠죠이때 인증을 유지하기 위한 방법으로세션과 토큰을 꼽아볼 수 있습니다먼저 세션부터 살펴보겠습니다세션은 서버가 클라이언트와 상호작용을 유지하기 위해서서버 내에 클라이언트의 상태 정보를 저장하는 방식입니다아까 편의점 예시를 다시 한번 들어보겠습니다매장 점원이 있었고요저희가 주류를 구매하려고 했었죠그리고 신분증을 제시해야만 했습니다신분증 제시를 다 마치고즉 인증과 인간을 다 마치고저희가 술을 다 구매할 수 있었습니다근데 이때 매장 점원이이제 저희의 얼굴을 기억한다고 해봅시다그러면 저희가다시 주류를 구매하러 갔을 때 이 매장 점원이 다시신분증을 제시하라고 하지 않고그냥 아 살 수 있습니다 라고 할 수 있겠죠이것이 세션이 동작하는 방식과 유사합니다실제로 동작과정을 살펴보겠습니다클라이언트가 계정과 비밀번호를 서버에게 보내서로그인 요청을 합니다그럼 서버는 DB를 찔러봐서 인증이 마무리될 수 있겠죠그러면 이제 이 사용자가 인증이 된 사용자라는 것을기록을 해둡니다 이 사용자를 기록을 해두는데이때 사용자마다 고유한 식별자인세션 아이디를 발급을 해서 이것을 클라이언트에게 보내줍니다그럼 클라이언트는 이것을 기록을 해두었다가이후 인가가 필요한 다른 절차에서이 세션 아이디를 함께 보내게 됩니다그러면 서버는 아까와 같이 디비를 찌를 필요는 없이이미 기록해 두었던 세션 아이디를 비교함으로써이 사람이 이미 인증이 완료된 사용자라는 것을 알고이후 인가 절차를 밟게 되는 것입니다자 이번엔 토큰입니다토큰은 사용자 인증에 대해정보가 담긴 징표라고 볼 수 있는데요이 토큰에 대해보다 자세히 설명하기 위해서구체적으로 Json Web Token에 대해서 알아보겠습니다흔히 JWT라고 일컬어지는 것인데요이 친구는 이런 형태의 문자열입니다xxx.yy.zzz 이런 형태를 갖게 있는데요실제로 토큰 하나를 제가 보여드리자면 이렇게 긴데요발표의 편의를 위해서 짧게 만들어서사용을 해보겠습니다 이 각각의 문자들마다점으로 구분되는 문자들마다헤더, 페이로드, 시그니처로 구분이 됩니다먼저 헤더를 살펴보겠습니다헤더는 토큰의 유형과 서명에 사용된암호화 알고리즘에 대한 정보를 포함합니다Json Web Token이잖아요Json 형태로 이런 데이터가 담기게 되는 것이고요이렇게 문자열이 되는 이유는Base64 URL로 인코딩을 해놓았기 때문입니다다음은 페이로드입니다이 페이로드에는 사용자 정보혹은 토큰 정보 등이 들어갈 수 있게 되는데요예를 들어 이 토큰이 발행된 대상, 발행 시간,만료 시간 등이 여기 들어갈 수 있게 되는 것입니다똑같이 헤더와 같이 Base64 URL로 인코딩 됩니다마지막으로 시그니처입니다시그니처는 토큰의 무결성을 보장하고변절을 방지하기 위해 사용되는 굉장히 중요한 것인데요앞서 보았던 헤더와페이로드를 이 암호 알고리즘에 넣게 되고요또 토큰을 발행하는 사용자가 사용하는 비밀키와 함께암호 알고리즘을 통해서이 시그니처가 형성이 되게 됩니다이 시크릿키라는 것도일종의 문자열인데요토큰을 발행하는 사람이 자유롭게 커스텀할 수 있는 것입니다그래서 후추키라고 쓰던흔히 비밀번호에서 사용되는저런 것들을 쓰던 모두 관계가 없습니다그리고 만약 토큰을 발행한 사람이자신의 토큰의 변조 여부를 확인하려면이렇게 입력된 토큰에 자신의 비밀키를이 암호화 알고리즘에 같이 넣어봐서 나온 결과값이 이것과 같은지비교를 해봄으로써이 토큰의 변조 여부를 확인해 볼 수 있겠죠자 그러면 이런 토큰을 알아봤는데이게 동작 과정이 어떻게 되는지 살펴보겠습니다아까와 같이 계정과 비밀번호를 주고요 인증을 완료하고요이제 서버가 사용자가 인증이 됐다는 것도 확인을 했고사용자의 정보도 알고 있으니까자신의 비밀키를 통해서 토큰을 발행합니다그리고 이 발행한 토큰을 클라이언트에게 보내주고요클라이언트는 이걸 가지고 있다가차후 다른 요청을 보낼 때이것을 포함해서 보내게 됩니다그러면 서버는 이 토큰을 가지고이 비밀키를 사용해서 이 토큰을 풀어 본 다음에변조가 되지 않았다는 것을 확인하고어떤 사용자인지도 확인을 해서인가 절차를 밟게 되는 것입니다자 이렇게 세션과 토큰에 대해서 알아봤는데요이 두 가지를 한번비교를 해보겠습니다첫 번째 키워드는 확장성입니다이렇게 세션 방식이 사용되고 있었는데요사용자가 많아짐에 따라서버를 수평으로 확장을 해본다고 해볼게요그러면 이렇게 서버가 3대가 되었고이 중간에 로드밸런서가각각의 서버에게 업무를 분담을 해주고 있습니다이때 로그인 요청이 들어왔습니다로드밸런서가 하단에 있는 서버에게 이 업무를 분담했습니다그래서 이 서버에서 세션 아이디가 발급되었고이거를 클라이언트에게 보내 주었습니다이제 차후에 이 세션 아이디로클라이언트가 다시 요청을 보내 왔습니다근데 이 로드 밸런서가 아래에 있는 이 서버가 아니라중간에 있는 서버에게 이 업무를 분담했다고 생각해 봅시다그럼 이 서버는 이 서버와 같이세션 아이디를 갖고 있지 않기 때문에지금의 클라이언트가이미 인증이 완료된 사용자라는 것을 알지 못합니다그래서 인증이 안 되었다는 응답을 보내게 되는 것이죠즉 이렇게 세션은 확장적인 측면에 있어서이전과 같이 동작을 하지 못하고추가적인 조치를 필요로 합니다그래서 세션은확장에 굉장히 불리한 구조다라고 볼 수 있는 것입니다다음은 토큰인데요어떤 임의의 서버에서 토큰이 발행되어서클라이언트에 간 상황이라고 가정해봅시다이 토큰을 통해서 다시 사용자가 서버에게 요청을 보내죠이때는 로드 밸런서가 어떤 서버에게 이 업무를 분담하든지상관이 없게 됩니다왜냐하면 모두 동일한 시크릿 키를 가지고 있어서단지 이 토큰을 열어보고 변조가 되었는지사용자가 누구인지만 확인하면 되는 것이기 때문입니다즉, 토큰이 확장성에 있어서는더 유리한 구조다 라고 말씀드릴 수 있을 것 같습니다다음은 보안이라는 키워드입니다세션과 토큰이 각각 이런 식으로 동작을 하고 있는데해커가 나타났습니다해커가 먼저 세션 아이디를 탈취를 했다고 생각해 봅시다그러면 해커는 이 세션 아이디를 통해서마치 자신이 인증된 사용자인 양이 서버에 접근하려고 할 텐데요그럼 서버는 이 탈취된 세션 아이디를말 그대로 삭제를 해버릴 수가 있는 것입니다그러면 더 이상 이 탈취된 세션 아이디를 통해서서버에 접근하는 것은 불가능하게 됩니다반면에 이번에는 해커가 토큰을 탈취했다고 생각해 봅시다이 토큰을 통해서해커는 서버에 당연히 접근을 할 수가 있습니다왜냐하면 토큰을 가지고 있으니까요근데 서버는 이것을 막을 방도가 당장엔 없습니다왜냐하면 서버가이 토큰에 대한 정보를 전혀 관리하지 않고 있기 때문입니다즉, 보안 관련된 측면에서는 세션이 토큰보다더 안정적인 보안적인 이점을 가지고 있다 라고말씀드릴 수 있을 것 같습니다지금까지 발표 모두 마무리가 되었고요인증과 인가를 공부를 하면서결국에 제가 맞닿드리는 질문은 이런 것들이었습니다그래서 어떤 인증, 인가 구현 방식을 택할 것인가이유는 무엇인가제가 앞에서 말씀드렸던 것은 보완과 확장성이라는 키워드였는데요이것 말고도훨씬 더 많은 키워드를 검색하면공부하실 수 있을 건데요여러분들도 이러한 질문에 답을 하면서여러분들의 개발에인증과 인가를 적절한 방식을 택해서하시면 좋을 것 같습니다 이상입니다