Skip to content

Commit d5c73ff

Browse files
committed
Add JWT authentication
1 parent b7ba663 commit d5c73ff

File tree

7 files changed

+169
-47
lines changed

7 files changed

+169
-47
lines changed

apps/config/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.env

apps/question-service/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Ignore private key json file
22
cs3219-g24-firebase-adminsdk-9cm7h-b1675603ab.json
3+
cs3219-g24-staging-firebase-adminsdk-suafv-9c0d1b2299.json
34
test_create_api_results.txt
45
test_list_api_results.txt
56
test_update_api_results.txt

apps/question-service/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ require (
2525
github.com/go-chi/cors v1.2.1
2626
github.com/go-logr/logr v1.4.2 // indirect
2727
github.com/go-logr/stdr v1.2.2 // indirect
28-
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
28+
github.com/golang-jwt/jwt/v4 v4.5.0
2929
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
3030
github.com/golang/protobuf v1.5.4 // indirect
3131
github.com/google/s2a-go v0.1.8 // indirect

apps/question-service/main.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"net/http"
99
"os"
1010
"question-service/handlers"
11+
mymiddleware "question-service/middleware"
1112
"question-service/utils"
1213
"time"
1314

@@ -42,6 +43,12 @@ func main() {
4243
log.Fatal("Error loading .env file")
4344
}
4445

46+
// Load config/.env file
47+
err = godotenv.Load("../config/.env")
48+
if err != nil {
49+
log.Fatal("Error loading .env file")
50+
}
51+
4552
// Initialize Firestore client
4653
ctx := context.Background()
4754
firebaseCredentialPath := os.Getenv("FIREBASE_CREDENTIAL_PATH")
@@ -65,6 +72,7 @@ func main() {
6572
r := chi.NewRouter()
6673
r.Use(middleware.Logger)
6774
r.Use(middleware.Timeout(60 * time.Second))
75+
r.Use(mymiddleware.VerifyJWT)
6876

6977
r.Use(cors.Handler(cors.Options{
7078
// AllowedOrigins: []string{"http://localhost:3000"}, // Use this to allow specific origin hosts
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package middleware
2+
3+
import (
4+
"github.com/golang-jwt/jwt/v4"
5+
"net/http"
6+
"os"
7+
"strings"
8+
)
9+
10+
func VerifyJWT(next http.Handler) http.Handler {
11+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
12+
// Get the token from the Authorization header
13+
authHeader := r.Header.Get("Authorization")
14+
if authHeader == "" {
15+
http.Error(w, "Authorization header is missing", http.StatusUnauthorized)
16+
return
17+
}
18+
19+
// Split the header to get the token
20+
tokenString := strings.Split(authHeader, " ")[1]
21+
22+
// Retrieve the JWT secret from environment variables
23+
jwtSecret := []byte(os.Getenv("JWT_SECRET"))
24+
if jwtSecret == nil {
25+
http.Error(w, "JWT secret is not set", http.StatusInternalServerError)
26+
return
27+
}
28+
29+
// Parse the token
30+
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
31+
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
32+
return nil, http.ErrNotSupported
33+
}
34+
return jwtSecret, nil
35+
})
36+
37+
if err != nil || !token.Valid {
38+
http.Error(w, "Invalid token", http.StatusUnauthorized)
39+
return
40+
}
41+
42+
// Optionally, you can extract claims from the token and attach them to the request context
43+
next.ServeHTTP(w, r)
44+
})
45+
}

0 commit comments

Comments
 (0)