Go(Golang)에서 JWT 인증을 구현하기 위한 단계별 가이드

Linda Hamilton
풀어 주다: 2024-11-19 20:48:03
원래의
561명이 탐색했습니다.

웹사이트의 백엔드를 만들 때 우리가 듣게 되는 매우 중요한 용어 중 하나는 JWT 인증입니다. JWT 인증은 API를 보호하는 가장 널리 사용되는 방법 중 하나입니다. JWT는 JSON Web Token의 약자로, 당사자 간 정보를 JSON 객체로 안전하게 전송하는 방법을 정의하는 개방형 표준입니다. 이 기사에서는 JWT 인증에 대해 논의하고 가장 중요한 것은 Gin-Gonic을 사용하여 빠르고 효율적인 JWT 인증을 위한 전체 프로젝트를 생성할 것입니다. 웹사이트 또는 애플리케이션의 백엔드를 위한 레벨 인증 API입니다.

목차:

  • JWT 인증이란 무엇인가요?
  • 프로젝트 구조
  • 전제조건
  • 단계별 튜토리얼
  • 최종 결과
  • 출력
  • 결론

JWT 인증이란 무엇입니까?

JWT는 JSON Web Token의 약자로 당사자 간 정보를 JSON 객체로 전송하는 방법을 너무 안전하게 정의하는 개방형 표준입니다.

예를 통해 이를 이해해 보겠습니다. 우리가 호텔에 가서 프런트 데스크로 걸어가는데 접수원이 "무엇을 도와드릴까요?"라고 말하는 상황을 생각해 보세요. 나는 "안녕하세요, 제 이름은 Shubham입니다. 저는 컨퍼런스 참석을 위해 여기에 왔고 스폰서들이 제 호텔 비용을 지불하고 있습니다"라고 말하고 싶습니다. 접수원은 "알겠습니다. 좋아요! 몇 가지 사항을 확인해야 할 것 같습니다"라고 말합니다. 일반적으로 그들은 내가 누구인지 증명하기 위해 내 신분증을 확인해야 하며, 내가 올바른 사람임을 확인한 후에는 나에게 열쇠를 발급할 것입니다. 그리고 인증은 이 예와 매우 유사한 방식으로 작동합니다.

JWT 인증을 사용하면 서버에 "여기 내 사용자 이름과 비밀번호 또는 로그인 토큰은 이거예요"라고 요청하고 웹사이트에서는 "알겠습니다. 확인해 보겠습니다."라고 말합니다. 내 사용자 이름과 비밀번호가 정확하면 토큰이 제공됩니다. 이제 서버의 후속 요청에서 더 이상 내 사용자 이름과 비밀번호를 포함할 필요가 없습니다. 토큰을 가지고 호텔(웹사이트)에 체크인하고 체육관(데이터)에 액세스하고 수영장(정보)에 액세스할 수 있으며 호텔 객실(계정)에만 액세스할 수 있습니다. 기타 호텔 객실(다른 사용자의 계정) 이 토큰은 체크인 시간부터 체크아웃 시간까지 내 상태 동안에만 승인됩니다. 그 이후에는 아무 소용이 없습니다. 이제 호텔에서는 인증 없이도 사람들이 최소한 호텔을 볼 수 있고, 호텔에 들어올 때까지 호텔 주변의 공공 장소를 돌아다닐 수 있습니다. 마찬가지로 익명의 사용자로서 웹 사이트의 홈 페이지, 랜딩 페이지와 상호 작용할 수 있습니다. 등

JWT의 예는 다음과 같습니다.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ 
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

프로젝트 구조

프로젝트 구성은 이렇습니다. 작업 공간에도 비슷한 폴더 구조를 만들어야 합니다. 이 구조에는 6개의 폴더가 있습니다:

  1. 컨트롤러
  2. 데이터베이스
  3. 도우미
  4. 미들웨어
  5. 모델
  6. 경로

이 폴더 안에 해당 파일을 만듭니다.

Step-by-Step Guide to Implementing JWT Authentication in Go (Golang)

전제조건

  1. 이동 - 버전 1.18
  2. 몽고DB
  3. 단계별 튜토리얼

1단계. 모듈을 생성하여 프로젝트를 시작하겠습니다. 모듈 이름은 "jwt"이고 사용자 이름은 "1shubham7"이므로 다음을 입력하여 모듈을 초기화하겠습니다.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ 
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

이렇게 하면 go.mod 파일이 생성됩니다.

Step 2. main.go 파일을 생성하고 main.go에 웹서버를 생성해보겠습니다. 이를 위해 파일에 다음 코드를 추가하세요.

go mod init github.com/1shubham7/jwt
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

환경 변수를 검색하는 'os' 패키지입니다.
우리는 gin-gonic 패키지를 사용하여 웹 서버를 만들고 있습니다.
나중에 경로 패키지를 생성하겠습니다.
AuthRoutes(), UserRoutes()는 경로 패키지의 파일 내부 함수이며 나중에 생성할 것입니다.

3단계. gin-gonic 패키지 다운로드:

package main
import(
    "github.com/gin-gonic/gin"
    "os"
    routes "github.com/1shubham7/jwt/routes"
    "github.com/joho/godotenv"
    "log"
)
func main() {
    err := godotenv.Load(".env")
    if err != nil {
        log.Fatal("Error locading the .env file")
    }
    port := os.Getenv("PORT")
    if port == "" {
        port = "1111"
    }
    router := gin.New()
    router.Use(gin.Logger())
    routes.AuthRoutes(router)
    routes.UserRoutes(router)
    // creating two APIs
    router.GET("/api-1", func(c *gin.Context){
        c.JSON(200, gin.H{"success":"Access granted for api-1"})
    })
    router.GET("api-2", func(c *gin.Context){
        c.JSON(200, gin.H{"success":"Access granted for api-2"})
    })
    router.Run(":" + port)
}
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

4단계. models 폴더를 생성하고 그 안에 userModel.go 파일을 생성합니다. userModel.go 내부에 다음 코드를 입력하세요:

go get github.com/gin-gonic/gin
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

User라는 구조체를 생성하고 구조체에 필요한 필드를 추가했습니다.

json:"first_name" 유효성 검사:"required, min=2, max=100" 이것을 필드 태그라고 하며, go 코드를 JSON 및 JSON으로 디코딩하고 인코딩하는 동안 사용됩니다.
여기서 유효성 검사:"required, min=2, max=100" 이는 특정 필드가 최소 2자에서 최대 100자여야 하는지 확인하는 데 사용됩니다.

5단계. 데이터베이스 폴더를 생성하고 그 안에 DatabaseConnection.go 파일을 생성하고 그 안에 다음 코드를 입력하세요.

package models
import (
    "go.mongodb.org/mongo-driver/bson/primitive"
    "time"
)
type User struct {
    ID            primitive.ObjectID `bson:"id"`
    First_name    *string            `json:"first_name" validate:"required, min=2, max=100"`
    Last_name     *string            `json:"last_name" validate:"required, min=2, max=100"`
    Password      *string            `json:"password" validate:"required, min=6"`
    Email         *string            `json:"email" validate:"email, required"` //validate email means it should have an @
    Phone         *string            `json:"phone" validate:"required"`
    Token         *string            `json:"token"`
    User_type     *string            `json:"user_type" validate:"required, eq=ADMIN|eq=USER"`
    Refresh_token *string            `json:"refresh_token"`
    Created_at    time.Time          `json:"created_at"`
    Updated_at    time.Time          `json:"updated_at"`
    User_id       string             `json:"user_id"`
}
로그인 후 복사
로그인 후 복사

'mongo' 패키지도 다운로드하세요.

package database
import (
    "fmt"
    "log"
    "os"
    "time"
    "context"
    "github.com/joho/godotenv"
    "go.mongodb.org/mongo-driver/mongo"
    "go/mongodb.org/mongo-driver/mongo/options"
)
func DBinstance() *mongo.Client{
    err := godotenv.Load(".env")
    if err != nil {
        log.Fatal("Error locading the .env file")
    }
    MongoDb := os.Getenv("THE_MONGODB_URL")
    client, err := mongo.NewClient(options.Client().ApplyURI(MongoDb))
    if err != nil {
        log.Fatal(err)
    }
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    err = client.Connect(ctx)
    if err!=nil{
        log.Fatal(err)
    }
    fmt.Println("Connected to MongoDB!!")
    return client
}
var Client *mongo.Client = DBinstance()
func OpenCollection(client *mongo.Client, collectionName string) *mongo.Collection {
    var collection *mongo.Collection = client.Database("cluster0").Collection(collectionName)
    return collection
}
로그인 후 복사
로그인 후 복사

여기서 mongo 데이터베이스를 애플리케이션과 연결합니다.

메인 디렉터리의 .env 파일에 설정할 환경 변수를 로드하기 위해 'godotenv'를 사용하고 있습니다.
DBinstance 함수에서는 .env 파일에서 "THE_MONGODB_URL" 값을 가져와(이후 단계에서 생성) 해당 값을 사용하여 새 mongoDB 클라이언트를 생성합니다.
'context'는 10초의 시간 초과를 갖는 데 사용됩니다.
OpenCollection Function()은 클라이언트와 collectionName을 입력으로 사용하고 이에 대한 컬렉션을 생성합니다.

6단계. 경로를 위해 authRouter와 userRouter라는 두 개의 서로 다른 파일을 생성합니다. authRouter에는 '/signup' 및 '/login'이 포함됩니다. 이는 모든 사람이 스스로 인증할 수 있도록 공개됩니다. userRouter는 모든 사람에게 공개되지 않습니다. 여기에는 '/users' 및 '/users/:user_id'가 포함됩니다.

routes라는 폴더를 만들고 여기에 두 개의 파일을 추가합니다.

  • userRouter.go
  • authRouter.go

userRouter.go에 다음 코드를 입력하세요.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ 
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

7단계. authRouter.go에 다음 코드를 입력하세요.

go mod init github.com/1shubham7/jwt
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

8단계. Controllers라는 폴더를 만들고 여기에 'userController.go'라는 파일을 추가합니다. 그 안에 다음 코드를 입력하세요.

package main
import(
    "github.com/gin-gonic/gin"
    "os"
    routes "github.com/1shubham7/jwt/routes"
    "github.com/joho/godotenv"
    "log"
)
func main() {
    err := godotenv.Load(".env")
    if err != nil {
        log.Fatal("Error locading the .env file")
    }
    port := os.Getenv("PORT")
    if port == "" {
        port = "1111"
    }
    router := gin.New()
    router.Use(gin.Logger())
    routes.AuthRoutes(router)
    routes.UserRoutes(router)
    // creating two APIs
    router.GET("/api-1", func(c *gin.Context){
        c.JSON(200, gin.H{"success":"Access granted for api-1"})
    })
    router.GET("api-2", func(c *gin.Context){
        c.JSON(200, gin.H{"success":"Access granted for api-2"})
    })
    router.Run(":" + port)
}
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

이 두 변수는 이전 코드에서 이미 사용되었습니다.

10단계. 먼저 GetUserById() 함수를 만들어 보겠습니다. GetUserById() 함수에 다음 코드를 입력하세요.

go get github.com/gin-gonic/gin
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

11단계. helpers라는 폴더를 만들고 여기에 authHelper.go라는 파일을 추가해 보겠습니다. authHelper.go에 다음 코드를 입력하세요.

package models
import (
    "go.mongodb.org/mongo-driver/bson/primitive"
    "time"
)
type User struct {
    ID            primitive.ObjectID `bson:"id"`
    First_name    *string            `json:"first_name" validate:"required, min=2, max=100"`
    Last_name     *string            `json:"last_name" validate:"required, min=2, max=100"`
    Password      *string            `json:"password" validate:"required, min=6"`
    Email         *string            `json:"email" validate:"email, required"` //validate email means it should have an @
    Phone         *string            `json:"phone" validate:"required"`
    Token         *string            `json:"token"`
    User_type     *string            `json:"user_type" validate:"required, eq=ADMIN|eq=USER"`
    Refresh_token *string            `json:"refresh_token"`
    Created_at    time.Time          `json:"created_at"`
    Updated_at    time.Time          `json:"updated_at"`
    User_id       string             `json:"user_id"`
}
로그인 후 복사
로그인 후 복사

MatchUserTypeToUserId() 함수는 사용자가 관리자인지 일반 사용자인지만 일치시킵니다.
MatchUserTypeToUserId() 내에서 CheckUserType() 함수를 사용하고 있습니다. 이는 모든 것이 괜찮은지 확인하는 것입니다(사용자로부터 얻은 user_type이 userType 변수와 동일한지 확인합니다.

12단계. 이제 userController.go의 SignUp() 기능을 사용할 수 있습니다.

package database
import (
    "fmt"
    "log"
    "os"
    "time"
    "context"
    "github.com/joho/godotenv"
    "go.mongodb.org/mongo-driver/mongo"
    "go/mongodb.org/mongo-driver/mongo/options"
)
func DBinstance() *mongo.Client{
    err := godotenv.Load(".env")
    if err != nil {
        log.Fatal("Error locading the .env file")
    }
    MongoDb := os.Getenv("THE_MONGODB_URL")
    client, err := mongo.NewClient(options.Client().ApplyURI(MongoDb))
    if err != nil {
        log.Fatal(err)
    }
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    err = client.Connect(ctx)
    if err!=nil{
        log.Fatal(err)
    }
    fmt.Println("Connected to MongoDB!!")
    return client
}
var Client *mongo.Client = DBinstance()
func OpenCollection(client *mongo.Client, collectionName string) *mongo.Collection {
    var collection *mongo.Collection = client.Database("cluster0").Collection(collectionName)
    return collection
}
로그인 후 복사
로그인 후 복사
  • 사용자 유형의 변수 사용자를 생성했습니다.

  • validationErr은 구조체 태그의 유효성을 검사하는 데 사용되며 이에 대해서는 이미 논의했습니다.

  • 또한 유효성을 검사하기 위해 count 변수를 사용하고 있습니다. 사용자 이메일이 포함된 문서를 이미 찾은 경우 개수는 0보다 크며 그러면 해당 오류를 처리할 수 있습니다(err)

  • 그런 다음 'time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))'를 사용하여 Created_at, Update_at 구조체 필드의 시간을 설정합니다. 사용자가 가입을 시도하면 SignUp() 함수가 실행되고 해당 특정 시간이 Created_at, Update_at 구조체 필드에 저장됩니다.

  • 그런 다음 다음 단계에서 동일한 패키지의 tokenHelper.go 파일에 생성할 generateAllTokens() 함수를 사용하여 토큰을 생성합니다.

  • user.password를 해싱하고 user.password를 해시된 비밀번호로 바꾸는 작업만 수행하는 HashPassword() 함수도 있습니다. 그것도 나중에 만들어보겠습니다.

  • 그런 다음 데이터와 토큰 등을 userCollection에 삽입합니다

  • 모든 것이 제대로 이루어지면 StatusOK를 돌려드리겠습니다.

13단계. helpers 폴더에 'tokenHelper.go'라는 파일을 만들고 그 안에 다음 코드를 입력하세요.

go get go.mongodb.org/mongo-driver/mongo
로그인 후 복사

또한 github.com/dgrijalva/jwt-go 패키지를 다운로드하세요:

package routes
import (
    "github.com/gin-gonic/gin"
    controllers "github.com/1shubham7/jwt/controllers"
    middleware "github.com/1shubham7/jwt/middleware"
)
// user should not be able to use userRoute without the token
func UserRoutes (incomingRoutes *gin.Engine) {
    incomingRoutes.Use(middleware.Authenticate())
    // user routes are public routes but these must be authenticated, that
    // is why we have Authenticate() before these
    incomingRoutes.GET("/users", controllers.GetUsers())
    incomingRoutes.GET("users/:user_id", controllers.GetUserById())
}
로그인 후 복사
  • 여기서는 토큰 생성을 위해 github.com/dgrijalva/jwt-go를 사용하고 있습니다.

  • 토큰 생성에 필요한 필드 이름을 사용하여 SignedDetails라는 구조체를 생성하고 있습니다.

  • NewWithClaims를 사용하여 새 토큰을 생성하고 클레임 및 RefreshClaims 구조체에 값을 제공하고 있습니다. 클레임에는 처음 사용자를 위한 토큰이 있고, RefreshClaims에는 사용자가 토큰을 새로 고쳐야 할 때 토큰이 있습니다. 즉, 이전에 현재 만료된 토큰이 있었습니다.

  • time.Now().Local().Add(time.Hour *time.Duration(120)).Unix()는 토큰 만료 설정에 사용됩니다.

  • 그런 다음 SignUp() 함수에서 사용하는 token,refreshToken 및 err 세 가지를 간단히 반환합니다.

14단계. SignUp() 함수와 동일한 파일에 9단계에서 이야기한 HashPassword() 함수를 생성해보겠습니다.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ 
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
  • 실제 비밀번호에서 해시된 비밀번호를 생성하는 데 사용되는 bcrypt 패키지의 generateFromPassword() 메소드를 사용하고 있습니다.

  • 해커가 시스템을 해킹하여 모든 비밀번호를 도용하는 것을 원하지 않으며 사용자의 개인정보 보호를 위해 이는 중요합니다.

  • []byte(바이트 배열)는 단순히 문자열입니다.

15단계. 'userController.go'에 Login() 함수를 생성하고 이후 단계에서는 Login()이 사용하는 함수를 생성할 수 있습니다.

go mod init github.com/1shubham7/jwt
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
  • 사용자 유형의 두 가지 변수, 즉 user와 Founduser를 생성합니다. 요청한 데이터를 사용자에게 제공합니다.

  • 'userCollection.FindOne(ctx, bson.M{"email": user.Email}).Decode(&foundUser)'의 도움으로 이메일을 통해 사용자를 찾고 있으며, 발견되면 foundUser 변수에 저장합니다.

  • 그런 다음 우리는 비밀번호를 확인하고 저장하기 위해 verifyPassword() 함수를 사용하고 있습니다. 우리는 verifyPassword()에서 포인터를 매개변수로 취하고 있다는 것을 기억하세요. 그렇지 않다면 매개변수 대신 매개변수에 있는 포인터의 새 인스턴스를 생성할 것입니다. 실제로 변경합니다.

  • 다음 단계에서 verifyPassword()를 생성하겠습니다.

  • 그런 다음 간단히 GenerateAllTokens() 및 UpdateAllTokens()를 사용하여 토큰 및 RefreshToken(기본적으로 토큰)을 생성하고 업데이트합니다.

  • 그리고 모든 단계에서 우리는 모두 오류를 처리하고 있습니다.

16단계. Login() 함수와 동일한 파일에 verifyPassword() 함수를 생성해 보겠습니다.

package main
import(
    "github.com/gin-gonic/gin"
    "os"
    routes "github.com/1shubham7/jwt/routes"
    "github.com/joho/godotenv"
    "log"
)
func main() {
    err := godotenv.Load(".env")
    if err != nil {
        log.Fatal("Error locading the .env file")
    }
    port := os.Getenv("PORT")
    if port == "" {
        port = "1111"
    }
    router := gin.New()
    router.Use(gin.Logger())
    routes.AuthRoutes(router)
    routes.UserRoutes(router)
    // creating two APIs
    router.GET("/api-1", func(c *gin.Context){
        c.JSON(200, gin.H{"success":"Access granted for api-1"})
    })
    router.GET("api-2", func(c *gin.Context){
        c.JSON(200, gin.H{"success":"Access granted for api-2"})
    })
    router.Run(":" + port)
}
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
  • 해시된 비밀번호를 비교하는 데 사용되는 bcrypt 패키지의 CompareHashAndPassword() 메서드를 사용하고 있습니다. 결과에 따라 부울 값을 반환합니다.

  • []byte(바이트 배열)는 단순한 문자열이지만 []byte는 비교에 도움이 됩니다.

17단계. 'tokenHelper.go' 파일에 UpdateAllTokens() 함수를 생성해 보겠습니다.

go get github.com/gin-gonic/gin
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
  • primitive.D 유형의 updateObj라는 변수를 생성하고 있습니다. MongoDB Go 드라이버의 원시.D 유형은 BSON 문서를 표현한 것입니다.

  • Append()는 실행될 때마다 updateObj에 키-값 쌍을 추가합니다.

  • 그런 다음 'time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))'를 사용하여 현재 시간(업데이트가 발생하고 함수가 실행되는 시간)을 Update_at로 업데이트합니다. .

  • 나머지 코드 블록은 mongoDB 컬렉션의 UpdateOne 메서드를 사용하여 업데이트를 수행합니다.

  • 마지막 단계에서는 오류가 발생할 경우를 대비해 오류 처리도 진행하고 있습니다.

18단계. 계속 진행하기 전에 go.mongodb.org/mongo-driver 패키지를 다운로드해 보겠습니다.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ 
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

19단계. 이제 GetUserById() 함수를 작업해 보겠습니다. GetUserById()는 사용자가 자신의 정보에 액세스하기 위한 것이며, 관리자는 모든 사용자 데이터에 액세스할 수 있고, 사용자는 자신의 데이터에만 액세스할 수 있다는 점을 기억하세요.

go mod init github.com/1shubham7/jwt
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
  • 요청에서 user_id를 가져와 userId 변수에 저장합니다.

  • User 유형의 user라는 변수를 생성합니다. 그런 다음 user_id를 사용하여 데이터베이스에서 사용자를 검색하고 user_id가 일치하면 해당 사람 정보를 사용자 변수에 저장합니다.

  • 정상이면 StatusOk

  • 또한 모든 단계에서 오류를 처리하고 있습니다.

20단계. 이제 GetUsers() 함수를 작업해 보겠습니다. GetUsers() 함수에는 모든 사용자의 데이터가 포함되므로 관리자만 액세스할 수 있다는 점을 기억하십시오. GetUserById(), Login() 및 SignUp() 함수와 동일한 파일에 GetUsers() 함수를 만듭니다.

package main
import(
    "github.com/gin-gonic/gin"
    "os"
    routes "github.com/1shubham7/jwt/routes"
    "github.com/joho/godotenv"
    "log"
)
func main() {
    err := godotenv.Load(".env")
    if err != nil {
        log.Fatal("Error locading the .env file")
    }
    port := os.Getenv("PORT")
    if port == "" {
        port = "1111"
    }
    router := gin.New()
    router.Use(gin.Logger())
    routes.AuthRoutes(router)
    routes.UserRoutes(router)
    // creating two APIs
    router.GET("/api-1", func(c *gin.Context){
        c.JSON(200, gin.H{"success":"Access granted for api-1"})
    })
    router.GET("api-2", func(c *gin.Context){
        c.JSON(200, gin.H{"success":"Access granted for api-2"})
    })
    router.Run(":" + port)
}
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
  • 먼저 요청이 관리자로부터 오는지 여부를 확인합니다. 이전 단계에서 만든 CheckUserType()을 사용하여 확인합니다.

  • 그런 다음 페이지당 원하는 레코드 수를 설정합니다.

  • 요청에서 recodePerPage를 가져와서 int로 변환하면 됩니다. 이 작업은 srtconv를 통해 수행됩니다.

  • recordPerPage 설정 시 오류가 발생하거나 RecordPerPage가 1보다 작을 경우 기본적으로 페이지당 레코드가 9개가 됩니다

  • 마찬가지로 'page' 변수에 페이지 번호를 사용하고 있습니다.

  • 기본적으로 페이지 번호는 1과 9 RecordPerPage로 설정됩니다.

  • 그런 다음 3개의 스테이지(matchStage, groupStage, projectStage)를 만들었습니다.

  • 그런 다음 Aggregate() 함수를 사용하여 Mongo 파이프라인에서 이 세 단계를 설정합니다

  • 또한 모든 단계에서 오류를 처리하고 있습니다.

21단계. 이제 'userController.go'가 준비되었습니다. 완료 후 'userController.go' 파일의 모습은 다음과 같습니다.

go get github.com/gin-gonic/gin
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

22단계. 이제 인증 부분을 작업할 수 있습니다. 이를 위해 우리는 인증된 미들웨어를 만들 것입니다. 'middleware'라는 폴더를 만들고 그 안에 'authMiddleware.go'라는 파일을 만듭니다. 파일에 다음 코드를 입력하세요:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ 
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

23단계. 이제 ValidateToken() 함수를 생성해 보겠습니다. 'tokenHelper.go'에서 이 함수를 생성하겠습니다.

go mod init github.com/1shubham7/jwt
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
  • ValidateToken은 signedToken을 가져와 오류 메시지와 함께 SignedDetails를 반환합니다. "" 오류가 없으면

  • ParseWithClaims() 함수는 토큰을 가져와서 token이라는 변수에 저장하는 데 사용됩니다.

  • 그런 다음 토큰에 대한 Claims 방법을 사용하여 토큰이 올바른지 확인합니다. 그리고 그 결과를 클레임 변수에 저장하고 있습니다.

  • 그런 다음 ExpiresAt() 함수를 사용하여 토큰이 만료되었는지 확인합니다. 현재 시간이 ExpiresAt 시간보다 크면 만료되었을 것입니다.

  • 그런 다음 메시지와 함께 클레임 변수를 반환하면 됩니다.

24단계. 이제 대부분 완료되었습니다. 'go mod tidy'를 수행해 보겠습니다. 이 명령은 go.mod 파일을 확인하고 설치했지만 사용하지 않는 모든 패키지/종속성을 삭제합니다. 사용 중이지만 아직 다운로드하지 않은 종속성을 다운로드합니다.

package main
import(
    "github.com/gin-gonic/gin"
    "os"
    routes "github.com/1shubham7/jwt/routes"
    "github.com/joho/godotenv"
    "log"
)
func main() {
    err := godotenv.Load(".env")
    if err != nil {
        log.Fatal("Error locading the .env file")
    }
    port := os.Getenv("PORT")
    if port == "" {
        port = "1111"
    }
    router := gin.New()
    router.Use(gin.Logger())
    routes.AuthRoutes(router)
    routes.UserRoutes(router)
    // creating two APIs
    router.GET("/api-1", func(c *gin.Context){
        c.JSON(200, gin.H{"success":"Access granted for api-1"})
    })
    router.GET("api-2", func(c *gin.Context){
        c.JSON(200, gin.H{"success":"Access granted for api-2"})
    })
    router.Run(":" + port)
}
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

Step-by-Step Guide to Implementing JWT Authentication in Go (Golang)

산출

이제 JWT 인증 프로젝트가 준비되었습니다. 마지막으로 애플리케이션을 실행하려면 터미널에 다음 명령을 입력하세요.

go get github.com/gin-gonic/gin
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

비슷한 출력을 얻게 됩니다.

Step-by-Step Guide to Implementing JWT Authentication in Go (Golang)

이렇게 하면 서버가 가동되고 실행되며, 요청을 보내고 응답을 받기 위해 컬이나 Postman API를 사용할 수 있습니다. 또는 이 API를 프런트엔드 프레임워크와 간단히 통합할 수도 있습니다. 이제 인증 API가 준비되었습니다. 안심하세요!

결론

이 기사에서는 JWT 인증을 생성하는 가장 빠른 방법 중 하나인 프로젝트에 Gin-Gonic 프레임워크를 사용하는 것에 대해 논의했습니다. 이것은 "단지 또 다른 인증 API"가 아닙니다. Gin은 NodeJS보다 300% 빠르므로 이 인증 API가 정말 빠르고 효율적입니다. 우리가 사용하는 프로젝트 구조도 업계 수준의 프로젝트 구조입니다. .env 파일에 SECRET_KEY를 저장하는 등의 추가 변경 작업을 수행하여 이 API를 더 좋게 만들 수 있습니다. 이 프로젝트의 소스 코드는 1Shubham7/go-jwt-token에서 찾을 수도 있습니다.

프로젝트를 생성하고 더 많은 기능을 추가하려면 모든 단계를 수행하고 코드를 직접 사용해 보면 더 잘 이해할 수 있습니다. 인증을 배우는 가장 좋은 방법은 자신만의 프로젝트를 만드는 것입니다.

위 내용은 Go(Golang)에서 JWT 인증을 구현하기 위한 단계별 가이드의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿