Skip to content

Commit 1570ea5

Browse files
committed
이메일로도 사용자 조회할 수 있도록 API 추가 (#18)
* add: 서비스 데이터는 public이므로 인증 없이 사용자 조회하도록 반영 * rename: 함수명 변경 * up: token 기반으로 사용자 조회하는 api 복구 * rename: 명확하게 이름 변경 * up: 명확하게 변수명 변경 * up: 중복 코드 함수화 * up: 문서화 * up: 누락된 http status 추가
1 parent 2d9afa6 commit 1570ea5

File tree

7 files changed

+188
-26
lines changed

7 files changed

+188
-26
lines changed

docs/docs.go

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ var doc = `{
122122
"tags": [
123123
"User"
124124
],
125-
"summary": "사용자 정보 조회",
125+
"summary": "Token으로 사용자 정보 조회",
126126
"parameters": [
127127
{
128128
"type": "string",
@@ -450,6 +450,50 @@ var doc = `{
450450
}
451451
}
452452
},
453+
"/users/{userEmail}": {
454+
"get": {
455+
"description": "사용자 이메일으로 사용자를 조회합니다.",
456+
"consumes": [
457+
"application/json"
458+
],
459+
"produces": [
460+
"application/json"
461+
],
462+
"tags": [
463+
"User"
464+
],
465+
"summary": "Email로 사용자 정보 조회",
466+
"parameters": [
467+
{
468+
"type": "string",
469+
"description": "사용자 Email",
470+
"name": "userEmail",
471+
"in": "path",
472+
"required": true
473+
}
474+
],
475+
"responses": {
476+
"200": {
477+
"description": "OK",
478+
"schema": {
479+
"$ref": "#/definitions/models.UserInfo"
480+
}
481+
},
482+
"400": {
483+
"description": ""
484+
},
485+
"404": {
486+
"description": ""
487+
},
488+
"500": {
489+
"description": "Internal Server Error",
490+
"schema": {
491+
"$ref": "#/definitions/models.ErrResponse"
492+
}
493+
}
494+
}
495+
}
496+
},
453497
"/version": {
454498
"get": {
455499
"description": "앱 버전을 응답합니다.",

docs/swagger.json

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@
102102
"tags": [
103103
"User"
104104
],
105-
"summary": "사용자 정보 조회",
105+
"summary": "Token으로 사용자 정보 조회",
106106
"parameters": [
107107
{
108108
"type": "string",
@@ -430,6 +430,50 @@
430430
}
431431
}
432432
},
433+
"/users/{userEmail}": {
434+
"get": {
435+
"description": "사용자 이메일으로 사용자를 조회합니다.",
436+
"consumes": [
437+
"application/json"
438+
],
439+
"produces": [
440+
"application/json"
441+
],
442+
"tags": [
443+
"User"
444+
],
445+
"summary": "Email로 사용자 정보 조회",
446+
"parameters": [
447+
{
448+
"type": "string",
449+
"description": "사용자 Email",
450+
"name": "userEmail",
451+
"in": "path",
452+
"required": true
453+
}
454+
],
455+
"responses": {
456+
"200": {
457+
"description": "OK",
458+
"schema": {
459+
"$ref": "#/definitions/models.UserInfo"
460+
}
461+
},
462+
"400": {
463+
"description": ""
464+
},
465+
"404": {
466+
"description": ""
467+
},
468+
"500": {
469+
"description": "Internal Server Error",
470+
"schema": {
471+
"$ref": "#/definitions/models.ErrResponse"
472+
}
473+
}
474+
}
475+
}
476+
},
433477
"/version": {
434478
"get": {
435479
"description": "앱 버전을 응답합니다.",

docs/swagger.yaml

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,36 @@ paths:
217217
description: Internal Server Error
218218
schema:
219219
$ref: '#/definitions/models.ErrResponse'
220-
summary: 사용자 정보 조회
220+
summary: Token으로 사용자 정보 조회
221+
tags:
222+
- User
223+
/users/{userEmail}:
224+
get:
225+
consumes:
226+
- application/json
227+
description: 사용자 이메일으로 사용자를 조회합니다.
228+
parameters:
229+
- description: 사용자 Email
230+
in: path
231+
name: userEmail
232+
required: true
233+
type: string
234+
produces:
235+
- application/json
236+
responses:
237+
"200":
238+
description: OK
239+
schema:
240+
$ref: '#/definitions/models.UserInfo'
241+
"400":
242+
description: ""
243+
"404":
244+
description: ""
245+
"500":
246+
description: Internal Server Error
247+
schema:
248+
$ref: '#/definitions/models.ErrResponse'
249+
summary: Email로 사용자 정보 조회
221250
tags:
222251
- User
223252
/users/login:

internal/app/handlers/users.go

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package handlers
22

33
import (
4-
"encoding/base64"
54
"errors"
65
"fmt"
76
"io/ioutil"
@@ -252,7 +251,7 @@ func UserKakaoLoginCallBack(c *gin.Context) {
252251
c.Redirect(http.StatusFound, redUrl)
253252
}
254253

255-
// @Summary 사용자 정보 조회
254+
// @Summary Token으로 사용자 정보 조회
256255
// @Description token 클레임에 있는 id 값으로 사용자를 조회합니다.
257256
// @Tags User
258257
// @Accept json
@@ -263,7 +262,7 @@ func UserKakaoLoginCallBack(c *gin.Context) {
263262
// @Failure 404
264263
// @Failure 500 {object} models.ErrResponse
265264
// @Router /users [get]
266-
func UserInfo(c *gin.Context) {
265+
func UserInfoTokenQuey(c *gin.Context) {
267266
au, err := auth.ExtractTokenMetadata(c.Request)
268267
if err != nil {
269268
c.JSON(http.StatusUnauthorized, models.ErrResponse{
@@ -272,10 +271,10 @@ func UserInfo(c *gin.Context) {
272271
return
273272
}
274273

275-
users := entitys.User{
274+
user := entitys.User{
276275
Id: uint(au.UserId),
277276
}
278-
if err := orm.Client.First(&users).Error; err != nil {
277+
if err := orm.Client.First(&user).Error; err != nil {
279278
if errors.Is(err, gorm.ErrRecordNotFound) {
280279
c.Status(http.StatusNotFound)
281280
return
@@ -287,26 +286,41 @@ func UserInfo(c *gin.Context) {
287286
return
288287
}
289288

290-
// [base64 encoding for any image](https://freshman.tech/snippets/go/image-to-base64/)
291-
var base64Encoding string
289+
res := models.NewUserInfo(user)
290+
c.JSON(http.StatusOK, res)
291+
}
292292

293-
// 이미지 파일의 콘텐츠 유형에 맞게 적절한 URI 체계 헤더를 추가합니다.
294-
mimeType := http.DetectContentType(users.AvatarImage)
295-
switch mimeType {
296-
case "image/jpeg":
297-
base64Encoding += "data:image/jpeg;base64,"
298-
case "image/png":
299-
base64Encoding += "data:image/png;base64,"
293+
// @Summary Email로 사용자 정보 조회
294+
// @Description 사용자 이메일으로 사용자를 조회합니다.
295+
// @Tags User
296+
// @Accept json
297+
// @Produce json
298+
// @Param userEmail path string true "사용자 Email"
299+
// @Success 200 {object} models.UserInfo
300+
// @Failure 400
301+
// @Failure 404
302+
// @Failure 500 {object} models.ErrResponse
303+
// @Router /users/{userEmail} [get]
304+
func UserInfoEmailQuey(c *gin.Context) {
305+
userEmail := c.Param("userEmail")
306+
if userEmail == "" {
307+
c.Status(http.StatusBadRequest)
308+
return
300309
}
301310

302-
base64Encoding += base64.StdEncoding.EncodeToString(users.AvatarImage)
303-
304-
res := models.UserInfo{
305-
Id: int(users.Id),
306-
Email: users.Email,
307-
Name: users.Name,
308-
AvatarImage: base64Encoding,
311+
user := entitys.User{}
312+
if err := orm.Client.Where("email = ?", userEmail).Find(&user).Error; err != nil {
313+
c.JSON(http.StatusInternalServerError, models.ErrResponse{
314+
Message: err.Error(),
315+
})
316+
return
309317
}
318+
if userEmail != user.Email {
319+
c.Status(http.StatusNotFound)
320+
return
321+
}
322+
323+
res := models.NewUserInfo(user)
310324
c.JSON(http.StatusOK, res)
311325
}
312326

internal/app/models/user-info.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,38 @@
11
package models
22

3+
import (
4+
"encoding/base64"
5+
"net/http"
6+
7+
"github.com/belf-kr/oauth-server/internal/app/entitys"
8+
)
9+
310
type UserInfo struct {
411
Id int `json:"id" binding:"required" example:"1"`
512
Email string `json:"email" binding:"required" example:"user01@test.com"`
613
Name string `json:"name" binding:"required" example:"사용자01"`
714
AvatarImage string `json:"avatarImage" binding:"required" example:"base64으로 인코딩된 이미지"`
815
}
16+
17+
func NewUserInfo(user entitys.User) UserInfo {
18+
// [base64 encoding for any image](https://freshman.tech/snippets/go/image-to-base64/)
19+
var base64Encoding string
20+
21+
// 이미지 파일의 콘텐츠 유형에 맞게 적절한 URI 체계 헤더를 추가합니다.
22+
mimeType := http.DetectContentType(user.AvatarImage)
23+
switch mimeType {
24+
case "image/jpeg":
25+
base64Encoding += "data:image/jpeg;base64,"
26+
case "image/png":
27+
base64Encoding += "data:image/png;base64,"
28+
}
29+
30+
base64Encoding += base64.StdEncoding.EncodeToString(user.AvatarImage)
31+
32+
return UserInfo{
33+
Id: int(user.Id),
34+
Email: user.Email,
35+
Name: user.Name,
36+
AvatarImage: base64Encoding,
37+
}
38+
}

internal/app/routers/router.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ func Use(api *gin.RouterGroup) {
1616
users.POST("/signup", handlers.UserSignup)
1717
users.POST("/login", handlers.UserLogin)
1818
users.GET("/login/kakao", handlers.UserKakaoLoginCallBack)
19-
users.GET("", middlewares.TokenAuthMiddleware(), handlers.UserInfo)
19+
users.GET("", middlewares.TokenAuthMiddleware(), handlers.UserInfoTokenQuey)
20+
users.GET(":userEmail", handlers.UserInfoEmailQuey)
2021
users.POST("/logout", middlewares.TokenAuthMiddleware(), handlers.UserLogout)
2122
users.GET("/token/valid", middlewares.TokenAuthMiddleware(), handlers.UserTokenValid)
2223
users.POST("/token/refresh", handlers.UserTokenRefresh)

internal/pkg/project/project.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ package project
22

33
const (
44
AppName string = "oauth-server"
5-
AppVersion string = "0.2.2"
5+
AppVersion string = "0.3.0"
66
)

0 commit comments

Comments
 (0)