이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
안녕하세요
오늘도 k-in 입니다.
1. 서론
"이것만 알면 나도 개발 전문가" 시리즈입니다.
"Gin 을 이용한 CRUD RESTful API 개발 Part6" 를 진행하겠습니다.
Part6 에서는 회원가입, 로그인 기능을 제공하기 위해 JWT 인증 기능을 추가해보도록 하겠습니다.
Part5 의 내용을 아직 학습하지 않았다면 아래의 링크로 접속하여 학습을 순서대로 이어가주세요.
2023.03.03 - [Go] - 고 (Golang) | 이것만 알면 나도 개발 전문가 | Gin 을 이용한 CRUD RESTful API 개발 Part-5
2. Part5 코드 내려 받기
코드는 이전 시간에 작성한 코드에 이어서 진행하도록 하겠습니다. 아래의 링크에 접근하여 clone 후 코드를 내려 받아 주세요.
https://bitbucket.org/kinstory/gin-tutorial/src/part5/
3. JWT(Json Web Token) 인증이란?
JWT 를 설명하기 전에 탄생 배경에 대해서 알아야 합니다. 서버에서 사용자의 정보를 알기 위한 방법은 무엇이 있을까요?
JWT 탄생 이전에는 서버에서 Session 정보를 저장하고 이를 관리하는 메커니즘을 구현하여 로그인된 사용자를 관리해 왔습니다.
이러한 방식을 Stateful 방식이라고 부릅니다.
그렇다면 Stateful 방식에는 어떤 문제가 있길레 JWT 가 등장한 것일까요?
Stateful 방식은 서버에서 Session 정보를 저장한다고 말하였습니다. 만약, 서버에 문제가 생긴다면 어떤일이 발생할까요?
서버는 세션 정보를 모두 잃고 로그인 상태인 사용자들은 로그아웃 상태가 될 것입니다.
물론 극단적인 예시이지만 Stateful 상태에서 서버의 중요성을 분명하게 보여줍니다. (실제로는 DB, 파일시스템, 캐시 등에 세션 정보를 저장하기 때문에 서버가 재부팅 되면 다시 살아납니다.)
Stateful 방식은 세션 정보 저장과 관련해서 IO 가 발생하게됩니다. 만약 사용자가 기하급수적으로 늘어난다면 서버는 사용자 요청 처리 연산에 더하여 세션 정보를 불러오는 과정이 필요합니다.
여기에 JWT는 사용자의 정보를 토큰에 보관하는 형태를 취하였습니다. 세션 정보를 저장하는 대신 사용자에게 자신을 증명할 정보를 변조가 불가능한 형태로 부여하는 방식(서명, Signing)을 채택한 것입니다. (서명이라고 한다면 우리가 아는 전자 서명과 동일합니다.)
이를 Stateless 방식이라고 부릅니다. 서버는 사용자가 제시한 인증 정보를 신뢰하여 권한을 부여합니다.
서버는 Stateless 방식이기 때문에 세션의 정보를 저장하거나 하지 않습니다. 세션을 저장할 우려가 없는 서버는 세션을 저장하는 서버보다 성능 상에서 이점을 가집니다.
위에서 정보를 토큰에 저장한다고 하였습니다. JWT 샘플을 한번 보겠습니다.
JWT 는 점(dot, ".")으로 구분된 Base64 인코딩 데이터의 모음으로 보입니다. Header 영역에는 알고리즘에 대한 정보, PAYLOAD 는 실제 데이터(데이터가 눈에 보이는 것이 JWT의 특징임)입니다. 마지막으로 서명 영역으로 실제 JWT 인증 서비스는 이 영역을 검증하여 토큰의 유효성(변조가 되지 않았음)을 최종 확인합니다.
JWT 인증 방식은 다음과 같습니다.
- 사용자는 인증 정보를 전송합니다.
- 인증서버 혹은 발급자(Issuer)는 JWT 를 발급 합니다.
- 발급된 JWT를 이용해 서비스에 리소스를 요청
- 토큰(JWT)가 유효하면 서비스에서 리소스를 전송
JWT 에 대해 개괄적인 이해를 마쳤으므로 회원가입과 로그인을 구현하여 이를 적용해 보면서 실제 쓰임을 이해해봅시다.
우선, 프로젝트 구조에 컨트롤러, 라우팅, 서비스의 개념을 담아볼까요?
컨트롤러, 라우팅, 미들웨어 그리고 서비스 로직
Part1 에서 우리는 프로젝트 폴더구조를 미리 정의하고 시작하였습니다.
각 폴더는 그 역할이 부여되어 있습니다. 이제 그 역할에 맞추어 프로젝트를 고도화 해야합니다.
먼저 폴더의 역할을 한번더 되짚어 볼까요? (볼드 처리된 불릿 항목에 초점을 맞추면 됩니다.)
- config : dotenv 와 같은 환경 설정 파일을 읽어오는 소스코드가 위치합니다.
- controllers : 비즈니스 로직을 정의하는 컨트롤러 코드가 위치합니다. 회원가입, 로그인 등의 처리를 담당합니다.
- middleware : JWT 와 같은 토큰을 역직렬화하고 이를 컨트롤러에 넘겨줍니다.
- routes : 정의된 컨트롤러에 접근하는 URI 를 정의합니다. 보통 라우팅을 설정한다고 말합니다.
- services : MongoDB 등의 데이터베이스 등에 접근 및 데이터를 끌어오는 역할을 합니다.
- templates : 메일 발송 및 렌더링할 HTML 템플릿 파일을 지정합니다. 여기서는 Go 에서 제공하는 기본 템플릿 라이브러리르 사용합니다.
- models: 사용자 요청 데이터 구조, 데이터베이스 데이터 구조 등을 정의하는 역할
- utils : 토큰 파싱, 메일 발송 등의 소스가 위치합니다.
- cmd: main 함수가 위치하며 서버 생성 등의 코드가 위치합니다.
만약 내용이 기억나지 않는다면 아래의 글을 참고해주세요.
2023.03.01 - [Go] - 고 (Golang) | 이것만 알면 나도 개발 전문가 | Gin 을 이용한 CRUD RESTful API 개발 Part-1
우리는 다음과 같은 접근 방식으로 위의 폴더들을 차례로 접근하여 코딩을 진행할 것입니다.
- 사용자로부터 송수신 할 데이터 규격을 정의 (models/user.model.go)
- DB 데이터의 규격을 정의 (models/user.model.go)
- DB 처리를 담당하는 서비스 로직 정의 (services/auth.service.go 와 auth.service.impl.go)
- 회원 가입, 로그인, 로그아웃 등을 처리할 비즈니스 로직 정의 (controllers/auth.controller.go)
- 정의된 로직에 대한 라우팅 추가 (routes/auth.routes.go)
- 메인 함수에 서비스, 컨트롤러, 라우팅을 초기화하고 Gin 웹 어플리케이션에 이를 등록
- 테스트
상당히 내용이 길고 내용이 복잡하기 때문에 이 부분은 구체적인 코딩 내용은 Part7 에서 본격적으로 다루도록 하겠습니다.
JWT 설명으로 글이 너무 늘어지네요 :(
맺음말
오늘은 "Gin 을 이용한 CRUD RESTful API 개발 Part6" 의 "JWT 인증 기능 추가하기 (1)" 를 진행하였습니다.
아래의 개념들을 다루어보았습니다.
- JWT 인증이란 무엇?
- JWT 데이터의 구조
- Gin 웹 프로젝트의 폴더 구조에 대해 Recap
- JWT 인증 구조를 구현하기 위한 구현 계획 작성
다음 시간에서는 실제 소스코드를 작성 하면서 회원가입, 로그인 등을 순차적으로 구현해보도록 하겠습니다.
이상으로 K-IN 이었습니다.
즐거운 하루되세요