├── .env ├── .gitignore ├── LICENSE ├── controllers └── userController.go ├── database └── databaseConnection.go ├── go.mod ├── go.sum ├── helpers ├── authHelper.go └── tokenHelper.go ├── main.go ├── middleware └── authMiddleware.go ├── models └── userModel.go └── routes ├── authRouter.go └── userRouter.go /.env: -------------------------------------------------------------------------------- 1 | PORT=9000 2 | MONGODB_URL=mongodb://localhost:27017/go-auth 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # Dependency directories (remove the comment below to include it) 15 | # vendor/ 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Akhil Sharma 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /controllers/userController.go: -------------------------------------------------------------------------------- 1 | package controllers 2 | 3 | import( 4 | "context" 5 | "fmt" 6 | "log" 7 | "strconv" 8 | "net/http" 9 | "time" 10 | "github.com/gin-gonic/gin" 11 | "github.com/go-playground/validator/v10" 12 | helper "github.com/akhil/golang-jwt-project/helpers" 13 | "github.com/akhil/golang-jwt-project/models" 14 | "github.com/akhil/golang-jwt-project/database" 15 | "golang.org/x/crypto/bcrypt" 16 | 17 | "go.mongodb.org/mongo-driver/bson" 18 | "go.mongodb.org/mongo-driver/bson/primitive" 19 | "go.mongodb.org/mongo-driver/mongo" 20 | ) 21 | 22 | var userCollection *mongo.Collection = database.OpenCollection(database.Client, "user") 23 | var validate = validator.New() 24 | 25 | func HashPassword(password string) string{ 26 | bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14) 27 | if err!=nil{ 28 | log.Panic(err) 29 | } 30 | return string(bytes) 31 | } 32 | 33 | func VerifyPassword(userPassword string, providedPassword string)(bool, string){ 34 | err := bcrypt.CompareHashAndPassword([]byte(providedPassword), []byte(userPassword)) 35 | check := true 36 | msg := "" 37 | 38 | if err!= nil { 39 | msg = fmt.Sprintf("email of password is incorrect") 40 | check=false 41 | } 42 | return check, msg 43 | } 44 | 45 | func Signup()gin.HandlerFunc{ 46 | 47 | return func(c *gin.Context){ 48 | var ctx, cancel = context.WithTimeout(context.Background(), 100*time.Second) 49 | var user models.User 50 | 51 | if err := c.BindJSON(&user); err != nil { 52 | c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) 53 | return 54 | } 55 | 56 | validationErr := validate.Struct(user) 57 | if validationErr != nil { 58 | c.JSON(http.StatusBadRequest, gin.H{"error":validationErr.Error()}) 59 | return 60 | } 61 | 62 | count, err := userCollection.CountDocuments(ctx, bson.M{"email":user.Email}) 63 | defer cancel() 64 | if err != nil { 65 | log.Panic(err) 66 | c.JSON(http.StatusInternalServerError, gin.H{"error":"error occured while checking for the email"}) 67 | } 68 | 69 | password := HashPassword(*user.Password) 70 | user.Password = &password 71 | 72 | count, err = userCollection.CountDocuments(ctx, bson.M{"phone":user.Phone}) 73 | defer cancel() 74 | if err!= nil { 75 | log.Panic(err) 76 | c.JSON(http.StatusInternalServerError, gin.H{"error":"error occured while checking for the phone number"}) 77 | } 78 | 79 | if count >0{ 80 | c.JSON(http.StatusInternalServerError, gin.H{"error":"this email or phone number already exists"}) 81 | } 82 | 83 | user.Created_at, _ = time.Parse(time.RFC3339, time.Now().Format(time.RFC3339)) 84 | user.Updated_at, _ = time.Parse(time.RFC3339, time.Now().Format(time.RFC3339)) 85 | user.ID = primitive.NewObjectID() 86 | user.User_id = user.ID.Hex() 87 | token, refreshToken, _ := helper.GenerateAllTokens(*user.Email, *user.First_name, *user.Last_name, *user.User_type, *&user.User_id) 88 | user.Token = &token 89 | user.Refresh_token = &refreshToken 90 | 91 | resultInsertionNumber, insertErr := userCollection.InsertOne(ctx, user) 92 | if insertErr !=nil { 93 | msg := fmt.Sprintf("User item was not created") 94 | c.JSON(http.StatusInternalServerError, gin.H{"error":msg}) 95 | return 96 | } 97 | defer cancel() 98 | c.JSON(http.StatusOK, resultInsertionNumber) 99 | } 100 | 101 | } 102 | 103 | func Login() gin.HandlerFunc{ 104 | return func(c *gin.Context){ 105 | var ctx, cancel = context.WithTimeout(context.Background(), 100*time.Second) 106 | var user models.User 107 | var foundUser models.User 108 | 109 | if err := c.BindJSON(&user); err != nil { 110 | c.JSON(http.StatusBadRequest, gin.H{"error":err.Error()}) 111 | return 112 | } 113 | 114 | err := userCollection.FindOne(ctx, bson.M{"email":user.Email}).Decode(&foundUser) 115 | defer cancel() 116 | if err != nil { 117 | c.JSON(http.StatusInternalServerError, gin.H{"error":"email or password is incorrect"}) 118 | return 119 | } 120 | 121 | passwordIsValid, msg := VerifyPassword(*user.Password, *foundUser.Password) 122 | defer cancel() 123 | if passwordIsValid != true{ 124 | c.JSON(http.StatusInternalServerError, gin.H{"error": msg}) 125 | return 126 | } 127 | 128 | if foundUser.Email == nil{ 129 | c.JSON(http.StatusInternalServerError, gin.H{"error":"user not found"}) 130 | } 131 | token, refreshToken, _ := helper.GenerateAllTokens(*foundUser.Email, *foundUser.First_name, *foundUser.Last_name, *foundUser.User_type, foundUser.User_id) 132 | helper.UpdateAllTokens(token, refreshToken, foundUser.User_id) 133 | err = userCollection.FindOne(ctx, bson.M{"user_id":foundUser.User_id}).Decode(&foundUser) 134 | 135 | if err != nil { 136 | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 137 | return 138 | } 139 | c.JSON(http.StatusOK, foundUser) 140 | } 141 | } 142 | 143 | func GetUsers() gin.HandlerFunc{ 144 | return func(c *gin.Context){ 145 | if err := helper.CheckUserType(c, "ADMIN"); err != nil { 146 | c.JSON(http.StatusBadRequest, gin.H{"error":err.Error()}) 147 | return 148 | } 149 | var ctx, cancel = context.WithTimeout(context.Background(), 100*time.Second) 150 | 151 | recordPerPage, err := strconv.Atoi(c.Query("recordPerPage")) 152 | if err != nil || recordPerPage <1{ 153 | recordPerPage = 10 154 | } 155 | page, err1 := strconv.Atoi(c.Query("page")) 156 | if err1 !=nil || page<1{ 157 | page = 1 158 | } 159 | 160 | startIndex := (page - 1) * recordPerPage 161 | startIndex, err = strconv.Atoi(c.Query("startIndex")) 162 | 163 | matchStage := bson.D{{"$match", bson.D{{}}}} 164 | groupStage := bson.D{{"$group", bson.D{ 165 | {"_id", bson.D{{"_id", "null"}}}, 166 | {"total_count", bson.D{{"$sum", 1}}}, 167 | {"data", bson.D{{"$push", "$$ROOT"}}}}}} 168 | projectStage := bson.D{ 169 | {"$project", bson.D{ 170 | {"_id", 0}, 171 | {"total_count", 1}, 172 | {"user_items", bson.D{{"$slice", []interface{}{"$data", startIndex, recordPerPage}}}},}}} 173 | result,err := userCollection.Aggregate(ctx, mongo.Pipeline{ 174 | matchStage, groupStage, projectStage}) 175 | defer cancel() 176 | if err!=nil{ 177 | c.JSON(http.StatusInternalServerError, gin.H{"error":"error occured while listing user items"}) 178 | } 179 | var allusers []bson.M 180 | if err = result.All(ctx, &allusers); err!=nil{ 181 | log.Fatal(err) 182 | } 183 | c.JSON(http.StatusOK, allusers[0])}} 184 | 185 | func GetUser() gin.HandlerFunc{ 186 | return func(c *gin.Context){ 187 | userId := c.Param("user_id") 188 | 189 | if err := helper.MatchUserTypeToUid(c, userId); err != nil { 190 | c.JSON(http.StatusBadRequest, gin.H{"error":err.Error()}) 191 | return 192 | } 193 | var ctx, cancel = context.WithTimeout(context.Background(), 100*time.Second) 194 | 195 | var user models.User 196 | err := userCollection.FindOne(ctx, bson.M{"user_id":userId}).Decode(&user) 197 | defer cancel() 198 | if err != nil{ 199 | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 200 | return 201 | } 202 | c.JSON(http.StatusOK, user) 203 | } 204 | } -------------------------------------------------------------------------------- /database/databaseConnection.go: -------------------------------------------------------------------------------- 1 | package database 2 | 3 | import( 4 | "fmt" 5 | "log" 6 | "time" 7 | "os" 8 | "context" 9 | "github.com/joho/godotenv" 10 | "go.mongodb.org/mongo-driver/mongo" 11 | "go.mongodb.org/mongo-driver/mongo/options" 12 | ) 13 | 14 | func DBinstance() *mongo.Client{ 15 | err := godotenv.Load(".env") 16 | if err!=nil{ 17 | log.Fatal("Error loading .env file") 18 | } 19 | 20 | MongoDb := os.Getenv("MONGODB_URL") 21 | 22 | client, err:= mongo.NewClient(options.Client().ApplyURI(MongoDb)) 23 | if err != nil { 24 | log.Fatal(err) 25 | } 26 | 27 | ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) 28 | defer cancel() 29 | err = client.Connect(ctx) 30 | if err != nil { 31 | log.Fatal(err) 32 | } 33 | fmt.Println("Connected to MongoDB!") 34 | 35 | return client 36 | } 37 | 38 | var Client *mongo.Client = DBinstance() 39 | 40 | func OpenCollection(client *mongo.Client, collectionName string) *mongo.Collection{ 41 | var collection *mongo.Collection = client.Database("cluster0").Collection(collectionName) 42 | return collection 43 | } -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/akhil/golang-jwt-project 2 | 3 | go 1.16 4 | 5 | require ( 6 | github.com/dgrijalva/jwt-go v3.2.0+incompatible 7 | github.com/gin-gonic/gin v1.7.4 8 | github.com/go-playground/validator/v10 v10.4.1 9 | github.com/joho/godotenv v1.3.0 10 | go.mongodb.org/mongo-driver v1.7.2 11 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 12 | ) 13 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 2 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 4 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 5 | github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= 6 | github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= 7 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= 8 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= 9 | github.com/gin-gonic/gin v1.7.4 h1:QmUZXrvJ9qZ3GfWvQ+2wnW/1ePrTEJqPKMYEU3lD/DM= 10 | github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= 11 | github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= 12 | github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= 13 | github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= 14 | github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= 15 | github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= 16 | github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= 17 | github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= 18 | github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= 19 | github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= 20 | github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 21 | github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= 22 | github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= 23 | github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= 24 | github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= 25 | github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= 26 | github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= 27 | github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= 28 | github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= 29 | github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= 30 | github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= 31 | github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= 32 | github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= 33 | github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= 34 | github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= 35 | github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= 36 | github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= 37 | github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= 38 | github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= 39 | github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= 40 | github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= 41 | github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= 42 | github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= 43 | github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= 44 | github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= 45 | github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= 46 | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 47 | github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= 48 | github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 49 | github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= 50 | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 51 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 52 | github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= 53 | github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= 54 | github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= 55 | github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= 56 | github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 57 | github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= 58 | github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= 59 | github.com/klauspost/compress v1.9.5 h1:U+CaK85mrNNb4k8BNOfgJtJ/gr6kswUCFj6miSzVC6M= 60 | github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= 61 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 62 | github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 63 | github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= 64 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 65 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 66 | github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= 67 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 68 | github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= 69 | github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= 70 | github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= 71 | github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= 72 | github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= 73 | github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 74 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= 75 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 76 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= 77 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 78 | github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= 79 | github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= 80 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 81 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 82 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 83 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 84 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 85 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 86 | github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= 87 | github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= 88 | github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= 89 | github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= 90 | github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= 91 | github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= 92 | github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= 93 | github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= 94 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 95 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 96 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 97 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 98 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 99 | github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= 100 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 101 | github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= 102 | github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= 103 | github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= 104 | github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= 105 | github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= 106 | github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= 107 | github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= 108 | github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= 109 | github.com/xdg-go/scram v1.0.2 h1:akYIkZ28e6A96dkWNJQu3nmCzH3YfwMPQExUYDaRv7w= 110 | github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= 111 | github.com/xdg-go/stringprep v1.0.2 h1:6iq84/ryjjeRmMJwxutI51F2GIPlP5BfTvXHeYjyhBc= 112 | github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= 113 | github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= 114 | github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= 115 | go.mongodb.org/mongo-driver v1.7.2 h1:pFttQyIiJUHEn50YfZgC9ECjITMT44oiN36uArf/OFg= 116 | go.mongodb.org/mongo-driver v1.7.2/go.mod h1:Q4oFMbo1+MSNqICAdYMlC/zSTrwCogR4R8NzkI+yfU8= 117 | golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 118 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 119 | golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= 120 | golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 121 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= 122 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 123 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 124 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 125 | golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 126 | golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 127 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 128 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= 129 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 130 | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 131 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 132 | golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 133 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 134 | golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 135 | golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 136 | golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 137 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg= 138 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 139 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 140 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 141 | golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= 142 | golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 143 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 144 | golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 145 | golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 146 | golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 147 | golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 148 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= 149 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 150 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 151 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= 152 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 153 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 154 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 155 | gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= 156 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 157 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= 158 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 159 | -------------------------------------------------------------------------------- /helpers/authHelper.go: -------------------------------------------------------------------------------- 1 | package helper 2 | 3 | import( 4 | "errors" 5 | "github.com/gin-gonic/gin" 6 | ) 7 | 8 | 9 | func CheckUserType(c *gin.Context, role string) (err error){ 10 | userType := c.GetString("user_type") 11 | err = nil 12 | if userType != role { 13 | err = errors.New("Unauthorized to access this resource") 14 | return err 15 | } 16 | return err 17 | } 18 | 19 | func MatchUserTypeToUid(c *gin.Context, userId string) (err error){ 20 | userType := c.GetString("user_type") 21 | uid := c.GetString("uid") 22 | err= nil 23 | 24 | if userType == "USER" && uid != userId { 25 | err = errors.New("Unauthorized to access this resource") 26 | return err 27 | } 28 | err = CheckUserType(c, userType) 29 | return err 30 | } -------------------------------------------------------------------------------- /helpers/tokenHelper.go: -------------------------------------------------------------------------------- 1 | package helper 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "log" 7 | "os" 8 | "time" 9 | "github.com/akhil/golang-jwt-project/database" 10 | jwt "github.com/dgrijalva/jwt-go" 11 | "go.mongodb.org/mongo-driver/bson" 12 | "go.mongodb.org/mongo-driver/bson/primitive" 13 | "go.mongodb.org/mongo-driver/mongo" 14 | "go.mongodb.org/mongo-driver/mongo/options" 15 | ) 16 | 17 | type SignedDetails struct{ 18 | Email string 19 | First_name string 20 | Last_name string 21 | Uid string 22 | User_type string 23 | jwt.StandardClaims 24 | } 25 | 26 | 27 | var userCollection *mongo.Collection = database.OpenCollection(database.Client, "user") 28 | 29 | var SECRET_KEY string = os.Getenv("SECRET_KEY") 30 | 31 | func GenerateAllTokens(email string, firstName string, lastName string, userType string, uid string) (signedToken string, signedRefreshToken string, err error){ 32 | claims := &SignedDetails{ 33 | Email : email, 34 | First_name: firstName, 35 | Last_name: lastName, 36 | Uid : uid, 37 | User_type: userType, 38 | StandardClaims: jwt.StandardClaims{ 39 | ExpiresAt: time.Now().Local().Add(time.Hour * time.Duration(24)).Unix(), 40 | }, 41 | } 42 | 43 | refreshClaims := &SignedDetails{ 44 | StandardClaims: jwt.StandardClaims{ 45 | ExpiresAt: time.Now().Local().Add(time.Hour * time.Duration(168)).Unix(), 46 | }, 47 | } 48 | 49 | token ,err := jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString([]byte(SECRET_KEY)) 50 | refreshToken, err := jwt.NewWithClaims(jwt.SigningMethodHS256, refreshClaims).SignedString([]byte(SECRET_KEY)) 51 | 52 | if err != nil { 53 | log.Panic(err) 54 | return 55 | } 56 | 57 | return token, refreshToken, err 58 | } 59 | 60 | 61 | func ValidateToken(signedToken string) (claims *SignedDetails, msg string){ 62 | token, err := jwt.ParseWithClaims( 63 | signedToken, 64 | &SignedDetails{}, 65 | func(token *jwt.Token)(interface{}, error){ 66 | return []byte(SECRET_KEY), nil 67 | }, 68 | ) 69 | 70 | if err != nil { 71 | msg=err.Error() 72 | return 73 | } 74 | 75 | claims, ok:= token.Claims.(*SignedDetails) 76 | if !ok{ 77 | msg = fmt.Sprintf("the token is invalid") 78 | msg = err.Error() 79 | return 80 | } 81 | 82 | if claims.ExpiresAt < time.Now().Local().Unix(){ 83 | msg = fmt.Sprintf("token is expired") 84 | msg = err.Error() 85 | return 86 | } 87 | return claims, msg 88 | } 89 | 90 | func UpdateAllTokens(signedToken string, signedRefreshToken string, userId string){ 91 | var ctx, cancel = context.WithTimeout(context.Background(), 100*time.Second) 92 | 93 | var updateObj primitive.D 94 | 95 | updateObj = append(updateObj, bson.E{"token", signedToken}) 96 | updateObj = append(updateObj, bson.E{"refresh_token", signedRefreshToken}) 97 | 98 | Updated_at, _ := time.Parse(time.RFC3339, time.Now().Format(time.RFC3339)) 99 | updateObj = append(updateObj, bson.E{"updated_at", Updated_at}) 100 | 101 | upsert := true 102 | filter := bson.M{"user_id":userId} 103 | opt := options.UpdateOptions{ 104 | Upsert: &upsert, 105 | } 106 | 107 | _, err := userCollection.UpdateOne( 108 | ctx, 109 | filter, 110 | bson.D{ 111 | {"$set", updateObj}, 112 | }, 113 | &opt, 114 | ) 115 | 116 | defer cancel() 117 | 118 | if err!=nil{ 119 | log.Panic(err) 120 | return 121 | } 122 | return 123 | } -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import( 4 | routes "github.com/akhil/golang-jwt-project/routes" 5 | "os" 6 | "log" 7 | "github.com/gin-gonic/gin" 8 | "github.com/joho/godotenv" 9 | ) 10 | 11 | func main(){ 12 | err := godotenv.Load(".env") 13 | 14 | if err != nil { 15 | log.Fatal("Error loading .env file") 16 | } 17 | port := os.Getenv("PORT") 18 | 19 | if port==""{ 20 | port="8000" 21 | } 22 | 23 | router := gin.New() 24 | router.Use(gin.Logger()) 25 | 26 | routes.AuthRoutes(router) 27 | routes.UserRoutes(router) 28 | 29 | router.GET("/api-1", func(c *gin.Context){ 30 | c.JSON(200, gin.H{"success":"Access granted for api-1"}) 31 | }) 32 | 33 | router.GET("/api-2", func(c *gin.Context){ 34 | c.JSON(200, gin.H{"success":"Access granted for api-2"}) 35 | }) 36 | 37 | router.Run(":" + port) 38 | } -------------------------------------------------------------------------------- /middleware/authMiddleware.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import( 4 | "fmt" 5 | "net/http" 6 | helper "github.com/akhil/golang-jwt-project/helpers" 7 | "github.com/gin-gonic/gin" 8 | ) 9 | 10 | func Authenticate() gin.HandlerFunc{ 11 | return func(c *gin.Context){ 12 | clientToken := c.Request.Header.Get("token") 13 | if clientToken == ""{ 14 | c.JSON(http.StatusInternalServerError, gin.H{"error":fmt.Sprintf("No Authorization header provided")}) 15 | c.Abort() 16 | return 17 | } 18 | 19 | claims, err := helper.ValidateToken(clientToken) 20 | if err !="" { 21 | c.JSON(http.StatusInternalServerError, gin.H{"error":err}) 22 | c.Abort() 23 | return 24 | } 25 | c.Set("email", claims.Email) 26 | c.Set("first_name", claims.First_name) 27 | c.Set("last_name", claims.Last_name) 28 | c.Set("uid",claims.Uid) 29 | c.Set("user_type", claims.User_type) 30 | c.Next() 31 | } 32 | } -------------------------------------------------------------------------------- /models/userModel.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import( 4 | "time" 5 | "go.mongodb.org/mongo-driver/bson/primitive" 6 | ) 7 | 8 | type User struct{ 9 | ID primitive.ObjectID `bson:"_id"` 10 | First_name *string `json:"first_name" validate:"required,min=2,max=100"` 11 | Last_name *string `json:"last_name" validate:"required,min=2,max=100"` 12 | Password *string `json:"Password" validate:"required,min=6"` 13 | Email *string `json:"email" validate:"email,required"` 14 | Phone *string `json:"phone" validate:"required"` 15 | Token *string `json:"token"` 16 | User_type *string `json:"user_type" validate:"required,eq=ADMIN|eq=USER"` 17 | Refresh_token *string `json:"refresh_token"` 18 | Created_at time.Time `json:"created_at"` 19 | Updated_at time.Time `json:"updated_at"` 20 | User_id string `json:"user_id"` 21 | } -------------------------------------------------------------------------------- /routes/authRouter.go: -------------------------------------------------------------------------------- 1 | package routes 2 | 3 | import( 4 | controller "github.com/akhil/golang-jwt-project/controllers" 5 | "github.com/gin-gonic/gin" 6 | ) 7 | 8 | func AuthRoutes(incomingRoutes *gin.Engine){ 9 | incomingRoutes.POST("users/signup", controller.Signup()) 10 | incomingRoutes.POST("users/login", controller.Login()) 11 | } -------------------------------------------------------------------------------- /routes/userRouter.go: -------------------------------------------------------------------------------- 1 | package routes 2 | 3 | import( 4 | controller "github.com/akhil/golang-jwt-project/controllers" 5 | "github.com/akhil/golang-jwt-project/middleware" 6 | "github.com/gin-gonic/gin" 7 | ) 8 | 9 | func UserRoutes(incomingRoutes *gin.Engine){ 10 | incomingRoutes.Use(middleware.Authenticate()) 11 | incomingRoutes.GET("/users", controller.GetUsers()) 12 | incomingRoutes.GET("/users/:user_id", controller.GetUser()) 13 | } --------------------------------------------------------------------------------