Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf235935

Browse files
committed
added jwt authentication
0 parents  commitf235935

20 files changed

+1383
-0
lines changed

‎.gitignore

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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+
.DS_Store
17+
TODO.md
18+
logs.txt
19+
.idea/
20+
secret.md
21+
app.env

‎Makefile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
dev:
2+
docker-compose up -d
3+
4+
dev-down:
5+
docker-compose down
6+
7+
go:
8+
go run main.go
9+

‎config/default.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package config
2+
3+
import (
4+
"time"
5+
6+
"github.com/spf13/viper"
7+
)
8+
9+
typeConfigstruct {
10+
DBUristring`mapstructure:"MONGODB_LOCAL_URI"`
11+
RedisUristring`mapstructure:"REDIS_URL"`
12+
Portstring`mapstructure:"PORT"`
13+
AccessTokenPrivateKeystring`mapstructure:"ACCESS_TOKEN_PRIVATE_KEY"`
14+
AccessTokenPublicKeystring`mapstructure:"ACCESS_TOKEN_PUBLIC_KEY"`
15+
RefreshTokenPrivateKeystring`mapstructure:"REFRESH_TOKEN_PRIVATE_KEY"`
16+
RefreshTokenPublicKeystring`mapstructure:"REFRESH_TOKEN_PUBLIC_KEY"`
17+
AccessTokenExpiresIn time.Duration`mapstructure:"ACCESS_TOKEN_EXPIRED_IN"`
18+
RefreshTokenExpiresIn time.Duration`mapstructure:"REFRESH_TOKEN_EXPIRED_IN"`
19+
AccessTokenMaxAgeint`mapstructure:"ACCESS_TOKEN_MAXAGE"`
20+
RefreshTokenMaxAgeint`mapstructure:"REFRESH_TOKEN_MAXAGE"`
21+
}
22+
23+
funcLoadConfig(pathstring) (configConfig,errerror) {
24+
viper.AddConfigPath(path)
25+
viper.SetConfigType("env")
26+
viper.SetConfigName("app")
27+
28+
viper.AutomaticEnv()
29+
30+
err=viper.ReadInConfig()
31+
iferr!=nil {
32+
return
33+
}
34+
35+
err=viper.Unmarshal(&config)
36+
return
37+
}

‎controllers/auth.controller.go

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
package controllers
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
7+
"github.com/gin-gonic/gin"
8+
"github.com/wpcodevo/golang-mongodb/config"
9+
"github.com/wpcodevo/golang-mongodb/models"
10+
"github.com/wpcodevo/golang-mongodb/services"
11+
"github.com/wpcodevo/golang-mongodb/utils"
12+
"go.mongodb.org/mongo-driver/mongo"
13+
)
14+
15+
typeAuthControllerstruct {
16+
authService services.AuthService
17+
userService services.UserService
18+
}
19+
20+
funcNewAuthController(authService services.AuthService,userService services.UserService)AuthController {
21+
returnAuthController{authService,userService}
22+
}
23+
24+
func (ac*AuthController)SignUpUser(ctx*gin.Context) {
25+
varuser*models.SignUpInput
26+
27+
iferr:=ctx.ShouldBindJSON(&user);err!=nil {
28+
ctx.JSON(http.StatusBadRequest, gin.H{"status":"fail","message":err.Error()})
29+
return
30+
}
31+
32+
ifuser.Password!=user.PasswordConfirm {
33+
ctx.JSON(http.StatusBadRequest, gin.H{"status":"fail","message":"Passwords do not match"})
34+
return
35+
}
36+
37+
newUser,err:=ac.authService.SignUpUser(user)
38+
39+
iferr!=nil {
40+
ctx.JSON(http.StatusBadGateway, gin.H{"status":"error","message":err.Error()})
41+
return
42+
}
43+
44+
ctx.JSON(http.StatusCreated, gin.H{"status":"success","data": gin.H{"user":models.FilteredResponse(newUser)}})
45+
}
46+
47+
func (ac*AuthController)SignInUser(ctx*gin.Context) {
48+
varcredentials*models.SignInInput
49+
50+
iferr:=ctx.ShouldBindJSON(&credentials);err!=nil {
51+
ctx.JSON(http.StatusBadRequest, gin.H{"status":"fail","message":err.Error()})
52+
return
53+
}
54+
55+
user,err:=ac.userService.FindUserByEmail(credentials.Email)
56+
iferr!=nil {
57+
iferr==mongo.ErrNoDocuments {
58+
ctx.JSON(http.StatusBadRequest, gin.H{"status":"fail","message":"Invalid email or password"})
59+
return
60+
}
61+
ctx.JSON(http.StatusBadRequest, gin.H{"status":"fail","message":err.Error()})
62+
return
63+
}
64+
65+
iferr:=utils.VerifyPassword(user.Password,credentials.Password);err!=nil {
66+
ctx.JSON(http.StatusBadRequest, gin.H{"status":"fail","message":"Invalid email or Password"})
67+
return
68+
}
69+
70+
config,_:=config.LoadConfig(".")
71+
72+
// Generate Tokens
73+
access_token,err:=utils.CreateToken(config.AccessTokenExpiresIn,user.ID,config.AccessTokenPrivateKey)
74+
iferr!=nil {
75+
ctx.JSON(http.StatusBadRequest, gin.H{"status":"fail","message":err.Error()})
76+
return
77+
}
78+
79+
refresh_token,err:=utils.CreateToken(config.RefreshTokenExpiresIn,user.ID,config.RefreshTokenPrivateKey)
80+
iferr!=nil {
81+
ctx.JSON(http.StatusBadRequest, gin.H{"status":"fail","message":err.Error()})
82+
return
83+
}
84+
85+
ctx.SetCookie("access_token",access_token,config.AccessTokenMaxAge*60,"/","localhost",false,true)
86+
ctx.SetCookie("refresh_token",refresh_token,config.RefreshTokenMaxAge*60,"/","localhost",false,true)
87+
ctx.SetCookie("logged_in","true",config.AccessTokenMaxAge*60,"/","localhost",false,false)
88+
89+
ctx.JSON(http.StatusOK, gin.H{"status":"success","access_token":access_token})
90+
}
91+
92+
func (ac*AuthController)RefreshAccessToken(ctx*gin.Context) {
93+
message:="could not refresh access token"
94+
95+
cookie,err:=ctx.Cookie("refresh_token")
96+
97+
iferr!=nil {
98+
ctx.AbortWithStatusJSON(http.StatusForbidden, gin.H{"status":"fail","message":message})
99+
return
100+
}
101+
102+
config,_:=config.LoadConfig(".")
103+
104+
sub,err:=utils.ValidateToken(cookie,config.RefreshTokenPublicKey)
105+
iferr!=nil {
106+
ctx.AbortWithStatusJSON(http.StatusForbidden, gin.H{"status":"fail","message":err.Error()})
107+
return
108+
}
109+
110+
user,err:=ac.userService.FindUserById(fmt.Sprint(sub))
111+
iferr!=nil {
112+
ctx.AbortWithStatusJSON(http.StatusForbidden, gin.H{"status":"fail","message":"the user belonging to this token no logger exists"})
113+
return
114+
}
115+
116+
access_token,err:=utils.CreateToken(config.AccessTokenExpiresIn,user.ID,config.AccessTokenPrivateKey)
117+
iferr!=nil {
118+
ctx.AbortWithStatusJSON(http.StatusForbidden, gin.H{"status":"fail","message":err.Error()})
119+
return
120+
}
121+
122+
ctx.SetCookie("access_token",access_token,config.AccessTokenMaxAge*60,"/","localhost",false,true)
123+
ctx.SetCookie("logged_in","true",config.AccessTokenMaxAge*60,"/","localhost",false,false)
124+
125+
ctx.JSON(http.StatusOK, gin.H{"status":"success","access_token":access_token})
126+
}

‎controllers/user.controller.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package controllers
2+
3+
import (
4+
"net/http"
5+
6+
"github.com/gin-gonic/gin"
7+
"github.com/wpcodevo/golang-mongodb/models"
8+
"github.com/wpcodevo/golang-mongodb/services"
9+
)
10+
11+
typeUserControllerstruct {
12+
userService services.UserService
13+
}
14+
15+
funcNewUserController(userService services.UserService)UserController {
16+
returnUserController{userService}
17+
}
18+
19+
func (uc*UserController)GetMe(ctx*gin.Context) {
20+
currentUser:=ctx.MustGet("currentUser").(*models.DBResponse)
21+
22+
ctx.JSON(http.StatusOK, gin.H{"status":"success","data": gin.H{"user":models.FilteredResponse(currentUser)}})
23+
}

‎docker-compose.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
version:'3'
2+
services:
3+
mongodb:
4+
image:mongo
5+
container_name:mongodb
6+
restart:always
7+
env_file:
8+
-./app.env
9+
10+
ports:
11+
-'6000:27017'
12+
volumes:
13+
-mongodb:/data/db
14+
15+
redis:
16+
image:redis:alpine
17+
container_name:redis
18+
ports:
19+
-'6379:6379'
20+
volumes:
21+
-redisDB:/data
22+
volumes:
23+
mongodb:
24+
redisDB:

‎example.env

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
PORT=8000
2+
3+
MONGO_INITDB_ROOT_USERNAME=root
4+
MONGO_INITDB_ROOT_PASSWORD=password123
5+
6+
MONGODB_LOCAL_URI=mongodb://root:password123@localhost:6000
7+
8+
REDIS_URL=localhost:6379
9+
10+
ACCESS_TOKEN_PRIVATE_KEY=LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlCUEFJQkFBSkJBTzVIKytVM0xrWC91SlRvRHhWN01CUURXSTdGU0l0VXNjbGFFKzlaUUg5Q2VpOGIxcUVmCnJxR0hSVDVWUis4c3UxVWtCUVpZTER3MnN3RTVWbjg5c0ZVQ0F3RUFBUUpCQUw4ZjRBMUlDSWEvQ2ZmdWR3TGMKNzRCdCtwOXg0TEZaZXMwdHdtV3Vha3hub3NaV0w4eVpSTUJpRmI4a25VL0hwb3piTnNxMmN1ZU9wKzVWdGRXNApiTlVDSVFENm9JdWxqcHdrZTFGY1VPaldnaXRQSjNnbFBma3NHVFBhdFYwYnJJVVI5d0loQVBOanJ1enB4ckhsCkUxRmJxeGtUNFZ5bWhCOU1HazU0Wk1jWnVjSmZOcjBUQWlFQWhML3UxOVZPdlVBWVd6Wjc3Y3JxMTdWSFBTcXoKUlhsZjd2TnJpdEg1ZGdjQ0lRRHR5QmFPdUxuNDlIOFIvZ2ZEZ1V1cjg3YWl5UHZ1YStxeEpXMzQrb0tFNXdJZwpQbG1KYXZsbW9jUG4rTkVRdGhLcTZuZFVYRGpXTTlTbktQQTVlUDZSUEs0PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQ==
11+
12+
ACCESS_TOKEN_PUBLIC_KEY=LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZ3d0RRWUpLb1pJaHZjTkFRRUJCUUFEU3dBd1NBSkJBTzVIKytVM0xrWC91SlRvRHhWN01CUURXSTdGU0l0VQpzY2xhRSs5WlFIOUNlaThiMXFFZnJxR0hSVDVWUis4c3UxVWtCUVpZTER3MnN3RTVWbjg5c0ZVQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQ==
13+
ACCESS_TOKEN_EXPIRED_IN=15m
14+
ACCESS_TOKEN_MAXAGE=15
15+
16+
17+
REFRESH_TOKEN_PRIVATE_KEY=LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlCT1FJQkFBSkJBSWFJcXZXeldCSndnYjR1SEhFQ01RdHFZMTI5b2F5RzVZMGlGcG51a0J1VHpRZVlQWkE4Cmx4OC9lTUh3Rys1MlJGR3VxMmE2N084d2s3TDR5dnY5dVY4Q0F3RUFBUUpBRUZ6aEJqOUk3LzAxR285N01CZUgKSlk5TUJLUEMzVHdQQVdwcSswL3p3UmE2ZkZtbXQ5NXNrN21qT3czRzNEZ3M5T2RTeWdsbTlVdndNWXh6SXFERAplUUloQVA5UStrMTBQbGxNd2ZJbDZtdjdTMFRYOGJDUlRaZVI1ZFZZb3FTeW40YmpBaUVBaHVUa2JtZ1NobFlZCnRyclNWZjN0QWZJcWNVUjZ3aDdMOXR5MVlvalZVRlVDSUhzOENlVHkwOWxrbkVTV0dvV09ZUEZVemhyc3Q2Z08KU3dKa2F2VFdKdndEQWlBdWhnVU8yeEFBaXZNdEdwUHVtb3hDam8zNjBMNXg4d012bWdGcEFYNW9uUUlnQzEvSwpNWG1heWtsaFRDeWtXRnpHMHBMWVdkNGRGdTI5M1M2ZUxJUlNIS009Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0t
18+
19+
REFRESH_TOKEN_PUBLIC_KEY=LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZ3d0RRWUpLb1pJaHZjTkFRRUJCUUFEU3dBd1NBSkJBSWFJcXZXeldCSndnYjR1SEhFQ01RdHFZMTI5b2F5Rwo1WTBpRnBudWtCdVR6UWVZUFpBOGx4OC9lTUh3Rys1MlJGR3VxMmE2N084d2s3TDR5dnY5dVY4Q0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQ==
20+
21+
REFRESH_TOKEN_EXPIRED_IN=60m
22+
REFRESH_TOKEN_MAXAGE=60

‎go.mod

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
modulegithub.com/wpcodevo/golang-mongodb
2+
3+
go1.18
4+
5+
require (
6+
github.com/gin-gonic/ginv1.7.7
7+
github.com/go-redis/redisv6.15.9+incompatible
8+
github.com/go-redis/redis/v8v8.11.5
9+
github.com/golang-jwt/jwtv3.2.2+incompatible
10+
github.com/spf13/viperv1.11.0
11+
go.mongodb.org/mongo-driverv1.9.1
12+
golang.org/x/cryptov0.0.0-20220513210258-46612604a0f9
13+
)
14+
15+
require (
16+
github.com/cespare/xxhash/v2v2.1.2// indirect
17+
github.com/dgryski/go-rendezvousv0.0.0-20200823014737-9f7001d12a5f// indirect
18+
github.com/fsnotify/fsnotifyv1.5.1// indirect
19+
github.com/gin-contrib/ssev0.1.0// indirect
20+
github.com/go-playground/localesv0.14.0// indirect
21+
github.com/go-playground/universal-translatorv0.18.0// indirect
22+
github.com/go-playground/validator/v10v10.11.0// indirect
23+
github.com/go-stack/stackv1.8.0// indirect
24+
github.com/golang/protobufv1.5.2// indirect
25+
github.com/golang/snappyv0.0.1// indirect
26+
github.com/hashicorp/hclv1.0.0// indirect
27+
github.com/json-iterator/gov1.1.12// indirect
28+
github.com/klauspost/compressv1.13.6// indirect
29+
github.com/leodido/go-urnv1.2.1// indirect
30+
github.com/magiconair/propertiesv1.8.6// indirect
31+
github.com/mattn/go-isattyv0.0.14// indirect
32+
github.com/mitchellh/mapstructurev1.4.3// indirect
33+
github.com/modern-go/concurrentv0.0.0-20180306012644-bacd9c7ef1dd// indirect
34+
github.com/modern-go/reflect2v1.0.2// indirect
35+
github.com/pelletier/go-tomlv1.9.4// indirect
36+
github.com/pelletier/go-toml/v2v2.0.0-beta.8// indirect
37+
github.com/pkg/errorsv0.9.1// indirect
38+
github.com/spf13/aferov1.8.2// indirect
39+
github.com/spf13/castv1.4.1// indirect
40+
github.com/spf13/jwalterweathermanv1.1.0// indirect
41+
github.com/spf13/pflagv1.0.5// indirect
42+
github.com/subosito/gotenvv1.2.0// indirect
43+
github.com/ugorji/go/codecv1.2.7// indirect
44+
github.com/xdg-go/pbkdf2v1.0.0// indirect
45+
github.com/xdg-go/scramv1.0.2// indirect
46+
github.com/xdg-go/stringprepv1.0.2// indirect
47+
github.com/youmark/pkcs8v0.0.0-20181117223130-1be2e3e5546d// indirect
48+
golang.org/x/syncv0.0.0-20201207232520-09787c993a3a// indirect
49+
golang.org/x/sysv0.0.0-20220513210249-45d2b4557a2a// indirect
50+
golang.org/x/textv0.3.7// indirect
51+
google.golang.org/protobufv1.28.0// indirect
52+
gopkg.in/ini.v1v1.66.4// indirect
53+
gopkg.in/yaml.v2v2.4.0// indirect
54+
gopkg.in/yaml.v3v3.0.0-20210107192922-496545a6307b// indirect
55+
)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp