golang-jwt-rieds
Go언어와 JWT(JSON Web Token)의 취약점을 Redis로 보완하는 프로젝트입니다.
프로젝트 소개
본 프로젝트는 기존의 JWT의 보안의 취약점을 보완하고자 Redis를 사용해서 취약점을 보완하는 프로젝트입니다.
프로젝트는 20221229-JWT에서 Redis를 사용하는 이유에 대한 궁금증에서부터 시작되었습니다.
작동 방식
회원가입
- 사용자가 회원가입을 요청합니다.
- 이메일과 패스워드를 받습니다.
- 모든 정보를 데이터베이스에 기록합니다.
데이터베이스에 평문 패스워드는 기록하지 않습니다.
bcrypt
로 암호화된 패스워드를 기록합니다.
- 정상적으로 완료 되었으면 사용자가에 회원가입 완료 응답을 보냅니다.
로그인
- 사용자가 로그인을 요청합니다.
- 사용자가 로그인을 요청한 정보가 올바른지 데이터베이스 저장된 정보와 검증합니다.
- 올바른 사용자가 맞다면
- Redis 기록된 Access Token(접근에 관여하는 토큰)와 Refresh Token(재발급에 관여하는 토큰)를 비교합니다.
REST API Docs
POST /auth/join
Request
{
"email": "me@hyunsang.dev",
"password": "q1w2e3r4",
"nick_name": "HyunSang Park"
}
Response
{
"meta": {
"status": "error",
"status_code": 200,
"success": true,
"message": "성공적으로 요청하신 유저를 만들었어요!"
},
"data": {
"id": 1,
"user_uuid": "a1ba7027-cb01-41dd-9416-352aeea0ca99",
"user_email": "me@hyunsang.dev",
"user_password": "$2a$10$q/4bNIrzUrO.N7m8jYLyvudFuP21Ek4Kv2Fm/SkNDZY1Xt0URWZKi",
"user_nickname": "HyunSang Park",
"created_at": "2023-01-30T15:49:51.91299+09:00",
"updated_at": "2023-01-30T15:49:51.91299+09:00"
},
"responsed_at": "2023-01-30T15:49:51.9261+09:00"
}
POST /auth/login
Request
{
"email": "me@hyunsang.dev",
"password": "q1w2e3r4"
}
Response
{
"meta": {
"status": "success",
"status_code": 200,
"success": true,
"message": "성공적으로 로그인을 완료했어요!"
},
"data": {
"user_uuid": "a1ba7027-cb01-41dd-9416-352aeea0ca99",
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NfdXVpZCI6IjYyZjM5OWUyLWM3ZTctNGZmMi1hNTY0LWUxMTQ5Y2NiOWYxNyIsImF1dGhvcml6ZWQiOnRydWUsImV4cCI6MTY3NTA2MjQ2OSwidXNlcl91dWlkIjoiYTFiYTcwMjctY2IwMS00MWRkLTk0MTYtMzUyYWVlYTBjYTk5In0.IxURueOzBaBbRJt7q-O26rXtH8g2_6dCXS9JiEz73kY",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NzU2NjYzNjksInJlZnJlc2hfdXVpZCI6Ijc1MjI2MmQ4LWU0ZjUtNDg5Zi05YjFmLTBiZDIyZmRhYjIyZSIsInVzZXJfdXVpZCI6ImExYmE3MDI3LWNiMDEtNDFkZC05NDE2LTM1MmFlZWEwY2E5OSJ9.gS_RH65_JUUYcPULj5tE-q36cG2guBzkQvcEHCpOEK8"
},
"responsed_at": "2023-01-30T15:52:49.567428+09:00"
}
![](https://github.com/dev-hyunsang/golang-jwt-redis/raw/9e197ba49ce0/assets/login-redis-01.png)
![](https://github.com/dev-hyunsang/golang-jwt-redis/raw/9e197ba49ce0/assets/login-redis-02.png)
POST /auth/logout
Request
Header:
Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NfdXVpZCI6ImNkNGJhMTcyLTRhZWMtNGVmYi1hNWNmLTZiZWVmZjVjYzk5OCIsImF1dGhvcml6ZWQiOnRydWUsImV4cCI6MTY3NTA2NjMzNiwidXNlcl91dWlkIjoiOTkzNjBmNzktMWJlZi00NzdmLTg2MzgtZWU0MTI3ZGZhYjE3In0.G5iW0m2SL4mMHZR13TAy-7It4gDAeVidcYoC5fc1vwc
access_token
으로 발급된 토큰을 이용해서 로그인 할 수 있습니다.
Response
{
"meta": {
"status": "ok",
"status_code": 200,
"success": true,
"message": "성공적으로 로그아웃 되셨습니다."
},
"data": 1,
"responsed_at": "2023-01-31T18:47:45.112174+09:00"
}
POST /todo/create
Request
Header:
Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NfdXVpZCI6ImNkNGJhMTcyLTRhZWMtNGVmYi1hNWNmLTZiZWVmZjVjYzk5OCIsImF1dGhvcml6ZWQiOnRydWUsImV4cCI6MTY3NTA2NjMzNiwidXNlcl91dWlkIjoiOTkzNjBmNzktMWJlZi00NzdmLTg2MzgtZWU0MTI3ZGZhYjE3In0.G5iW0m2SL4mMHZR13TAy-7It4gDAeVidcYoC5fc1vwc
Body:
{
"todo_title": "Hello, World!",
"todo_context": "Hello, World!"
}
Response
{
"meta": {
"status": "ok",
"status_code": 200,
"success": true,
"message": "성공적으로 새로운 할일을 생성했습니다."
},
"data": {
"id": 4,
"todo_uuid": "439c9657-1c25-41ee-a45e-90bbef0307d2",
"user_uuid": "99360f79-1bef-477f-8638-ee4127dfab17",
"todo_title": "Hello, World!",
"todo_context": "Hello, World!",
"updated_at": "2023-01-30T17:00:41.94033+09:00",
"crated_at": "2023-01-30T17:00:41.94033+09:00"
},
"responsed_at": "2023-01-30T17:00:41.951056+09:00"
}
POST /todo/update
Request
Header:
Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NfdXVpZCI6ImNkNGJhMTcyLTRhZWMtNGVmYi1hNWNmLTZiZWVmZjVjYzk5OCIsImF1dGhvcml6ZWQiOnRydWUsImV4cCI6MTY3NTA2NjMzNiwidXNlcl91dWlkIjoiOTkzNjBmNzktMWJlZi00NzdmLTg2MzgtZWU0MTI3ZGZhYjE3In0.G5iW0m2SL4mMHZR13TAy-7It4gDAeVidcYoC5fc1vwc
Body:
{
"todo_uuid": "0004bbf4-233f-4b03-93ac-e9728224acb1",
"todo_title": "Hello, World!2",
"todo_context": "Hello, World!2"
}
Response
{
"meta": {
"status": "ok",
"status_code": 200,
"success": true,
"message": "성공적으로 할일을 수정했어요!"
},
"data": 1,
"responsed_at": "2023-01-31T18:52:23.817192+09:00"
}
POST /todo/read
Request
Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NfdXVpZCI6ImU0YzNjZDA2LWU4ZjUtNDczMS1iYmJlLWZjN2U4Mjc3ZjdhZSIsImF1dGhvcml6ZWQiOnRydWUsImV4cCI6MTY3NjYyNTE2OCwidXNlcl91dWlkIjoiNDEzYzJlZDgtNDk1Ni00NjA1LWExMzItMGZhOWE1Y2FjYzM5In0.GwLb9vozU6rVCjvVSjzaqUpxVDnHfASisrA094yKrHg
Response
{
"meta": {
"status": "ok",
"status_code": 200,
"success": true,
"message": "성공적으로 할일들을 불러왔습니다."
},
"data": [
{
"id": 1,
"todo_uuid": "94567457-7866-4be9-8584-78a4d96fa3f1",
"user_uuid": "413c2ed8-4956-4605-a132-0fa9a5cacc39",
"todo_title": "Hello, World!",
"todo_context": "Hello, World!",
"updated_at": "2023-02-17T09:00:43Z",
"crated_at": "2023-02-17T09:00:43Z"
}
],
"responsed_at": "2023-02-17T18:10:37.835866+09:00"
}
POST /todo/delete
Request
Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NfdXVpZCI6ImU0YzNjZDA2LWU4ZjUtNDczMS1iYmJlLWZjN2U4Mjc3ZjdhZSIsImF1dGhvcml6ZWQiOnRydWUsImV4cCI6MTY3NjYyNTE2OCwidXNlcl91dWlkIjoiNDEzYzJlZDgtNDk1Ni00NjA1LWExMzItMGZhOWE1Y2FjYzM5In0.GwLb9vozU6rVCjvVSjzaqUpxVDnHfASisrA094yKrHg
{
"todo_uuid": "94567457-7866-4be9-8584-78a4d96fa3f1"
}
Response
{
"meta": {
"status": "ok",
"status_code": 200,
"success": true,
"message": "정상적으로 할일을 삭제했습니다."
},
"responsed_at": "2023-02-17T19:11:15.506825+09:00"
}
참고한 자료들