Skip to content

Commit 1562a69

Browse files
committed
first commit
0 parents  commit 1562a69

File tree

10 files changed

+688
-0
lines changed

10 files changed

+688
-0
lines changed

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Authentication using JWT in Golang
2+
3+
How to implement Authentication using JWT in Golang
4+
5+
## Installtion
6+
7+
Below command will Install all the dependencies recursively.
8+
9+
```bash
10+
go get -d ./...
11+
```
12+
13+
## Starting the GO server
14+
15+
Use the below command to create executable and the run executable.
16+
17+
```bash
18+
go build
19+
```
20+
21+

db.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"log"
6+
7+
"go.mongodb.org/mongo-driver/mongo"
8+
"go.mongodb.org/mongo-driver/mongo/options"
9+
)
10+
11+
// Client is exported Mongo Database client
12+
var Client *mongo.Client
13+
14+
// ConnectDatabase is used to connect the MongoDB database
15+
func ConnectDatabase() {
16+
log.Println("Database connecting...")
17+
// Set client options
18+
clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")
19+
20+
// Connect to MongoDB
21+
client, err := mongo.Connect(context.TODO(), clientOptions)
22+
Client = client
23+
if err != nil {
24+
log.Fatal(err)
25+
}
26+
27+
// Check the connection
28+
err = Client.Ping(context.TODO(), nil)
29+
30+
if err != nil {
31+
log.Fatal(err)
32+
}
33+
34+
log.Println("Database Connected.")
35+
}

jwt.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package main
2+
3+
import (
4+
"time"
5+
6+
"github.com/dgrijalva/jwt-go"
7+
)
8+
9+
var jwtSecretKey = []byte("jwt_secret_key")
10+
11+
// CreateJWT func will used to create the JWT while signing in and signing out
12+
func CreateJWT(email string) (response string, err error) {
13+
expirationTime := time.Now().Add(5 * time.Minute)
14+
claims := &Claims{
15+
Email: email,
16+
StandardClaims: jwt.StandardClaims{
17+
ExpiresAt: expirationTime.Unix(),
18+
},
19+
}
20+
21+
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
22+
tokenString, err := token.SignedString(jwtSecretKey)
23+
if err == nil {
24+
return tokenString, nil
25+
}
26+
return "", err
27+
}
28+
29+
// VerifyToken func will used to Verify the JWT Token while using APIS
30+
func VerifyToken(tokenString string) (email string, err error) {
31+
claims := &Claims{}
32+
33+
token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
34+
return jwtSecretKey, nil
35+
})
36+
37+
if token != nil {
38+
return claims.Email, nil
39+
}
40+
return "", err
41+
}

routes-handlers.go

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"net/http"
7+
"strings"
8+
"time"
9+
10+
"go.mongodb.org/mongo-driver/bson"
11+
)
12+
13+
// RenderHome Rendering the Home Page
14+
func RenderHome(response http.ResponseWriter, request *http.Request) {
15+
http.ServeFile(response, request, "views/profile.html")
16+
}
17+
18+
// RenderLogin Rendering the Login Page
19+
func RenderLogin(response http.ResponseWriter, request *http.Request) {
20+
http.ServeFile(response, request, "views/login.html")
21+
}
22+
23+
// RenderRegister Rendering the Registration Page
24+
func RenderRegister(response http.ResponseWriter, request *http.Request) {
25+
http.ServeFile(response, request, "views/register.html")
26+
}
27+
28+
// SignInUser Used for Signing In the Users
29+
func SignInUser(response http.ResponseWriter, request *http.Request) {
30+
var loginRequest LoginParams
31+
var result UserDetails
32+
var errorResponse = ErrorResponse{
33+
Code: http.StatusInternalServerError, Message: "It's not you it's me.",
34+
}
35+
36+
decoder := json.NewDecoder(request.Body)
37+
decoderErr := decoder.Decode(&loginRequest)
38+
defer request.Body.Close()
39+
40+
if decoderErr != nil {
41+
returnErrorResponse(response, request, errorResponse)
42+
} else {
43+
errorResponse.Code = http.StatusBadRequest
44+
if loginRequest.Email == "" {
45+
errorResponse.Message = "Last Name can't be empty"
46+
returnErrorResponse(response, request, errorResponse)
47+
} else if loginRequest.Password == "" {
48+
errorResponse.Message = "Password can't be empty"
49+
returnErrorResponse(response, request, errorResponse)
50+
} else {
51+
52+
collection := Client.Database("test").Collection("users")
53+
54+
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
55+
var err = collection.FindOne(ctx, bson.M{
56+
"email": loginRequest.Email,
57+
"password": loginRequest.Password,
58+
}).Decode(&result)
59+
60+
defer cancel()
61+
62+
if err != nil {
63+
returnErrorResponse(response, request, errorResponse)
64+
} else {
65+
tokenString, _ := CreateJWT(loginRequest.Email)
66+
67+
if tokenString == "" {
68+
returnErrorResponse(response, request, errorResponse)
69+
}
70+
71+
var successResponse = SuccessResponse{
72+
Code: http.StatusOK,
73+
Message: "You are registered, login again",
74+
Response: SuccessfulLoginResponse{
75+
AuthToken: tokenString,
76+
Email: loginRequest.Email,
77+
},
78+
}
79+
80+
successJSONResponse, jsonError := json.Marshal(successResponse)
81+
82+
if jsonError != nil {
83+
returnErrorResponse(response, request, errorResponse)
84+
}
85+
response.Header().Set("Content-Type", "application/json")
86+
response.Write(successJSONResponse)
87+
}
88+
}
89+
}
90+
}
91+
92+
// SignUpUser Used for Signing up the Users
93+
func SignUpUser(response http.ResponseWriter, request *http.Request) {
94+
var registationRequest RegistationParams
95+
var errorResponse = ErrorResponse{
96+
Code: http.StatusInternalServerError, Message: "It's not you it's me.",
97+
}
98+
99+
decoder := json.NewDecoder(request.Body)
100+
decoderErr := decoder.Decode(&registationRequest)
101+
defer request.Body.Close()
102+
103+
if decoderErr != nil {
104+
returnErrorResponse(response, request, errorResponse)
105+
} else {
106+
errorResponse.Code = http.StatusBadRequest
107+
if registationRequest.Name == "" {
108+
errorResponse.Message = "First Name can't be empty"
109+
returnErrorResponse(response, request, errorResponse)
110+
} else if registationRequest.Email == "" {
111+
errorResponse.Message = "Last Name can't be empty"
112+
returnErrorResponse(response, request, errorResponse)
113+
} else if registationRequest.Password == "" {
114+
errorResponse.Message = "Country can't be empty"
115+
returnErrorResponse(response, request, errorResponse)
116+
} else {
117+
tokenString, _ := CreateJWT(registationRequest.Email)
118+
119+
if tokenString == "" {
120+
returnErrorResponse(response, request, errorResponse)
121+
}
122+
123+
var registrationResponse = SuccessfulLoginResponse{
124+
AuthToken: tokenString,
125+
Email: registationRequest.Email,
126+
}
127+
128+
collection := Client.Database("test").Collection("users")
129+
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
130+
_, databaseErr := collection.InsertOne(ctx, bson.M{
131+
"email": registationRequest.Email,
132+
"password": registationRequest.Password,
133+
"name": registationRequest.Name,
134+
})
135+
defer cancel()
136+
137+
if databaseErr != nil {
138+
returnErrorResponse(response, request, errorResponse)
139+
}
140+
141+
var successResponse = SuccessResponse{
142+
Code: http.StatusOK,
143+
Message: "You are registered, login again",
144+
Response: registrationResponse,
145+
}
146+
147+
successJSONResponse, jsonError := json.Marshal(successResponse)
148+
149+
if jsonError != nil {
150+
returnErrorResponse(response, request, errorResponse)
151+
}
152+
response.Header().Set("Content-Type", "application/json")
153+
response.WriteHeader(successResponse.Code)
154+
response.Write(successJSONResponse)
155+
}
156+
}
157+
}
158+
159+
// GetUserDetails Used for getting the user details using user token
160+
func GetUserDetails(response http.ResponseWriter, request *http.Request) {
161+
var result UserDetails
162+
var errorResponse = ErrorResponse{
163+
Code: http.StatusInternalServerError, Message: "It's not you it's me.",
164+
}
165+
bearerToken := request.Header.Get("Authorization")
166+
var authorizationToken = strings.Split(bearerToken, " ")[1]
167+
168+
email, _ := VerifyToken(authorizationToken)
169+
if email == "" {
170+
returnErrorResponse(response, request, errorResponse)
171+
} else {
172+
collection := Client.Database("test").Collection("users")
173+
174+
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
175+
var err = collection.FindOne(ctx, bson.M{
176+
"email": email,
177+
}).Decode(&result)
178+
179+
defer cancel()
180+
181+
if err != nil {
182+
returnErrorResponse(response, request, errorResponse)
183+
} else {
184+
var successResponse = SuccessResponse{
185+
Code: http.StatusOK,
186+
Message: "You are logged in successfully",
187+
Response: result.Name,
188+
}
189+
190+
successJSONResponse, jsonError := json.Marshal(successResponse)
191+
192+
if jsonError != nil {
193+
returnErrorResponse(response, request, errorResponse)
194+
}
195+
response.Header().Set("Content-Type", "application/json")
196+
response.Write(successJSONResponse)
197+
}
198+
}
199+
}
200+
201+
func returnErrorResponse(response http.ResponseWriter, request *http.Request, errorMesage ErrorResponse) {
202+
httpResponse := &ErrorResponse{Code: errorMesage.Code, Message: errorMesage.Message}
203+
jsonResponse, err := json.Marshal(httpResponse)
204+
if err != nil {
205+
panic(err)
206+
}
207+
response.Header().Set("Content-Type", "application/json")
208+
response.WriteHeader(errorMesage.Code)
209+
response.Write(jsonResponse)
210+
}

routes.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package main
2+
3+
import (
4+
"log"
5+
6+
"github.com/gorilla/mux"
7+
)
8+
9+
// AddApproutes will add the routes for the application
10+
func AddApproutes(route *mux.Router) {
11+
12+
log.Println("Loadeding Routes...")
13+
14+
route.HandleFunc("/", RenderHome)
15+
16+
route.HandleFunc("/login", RenderLogin)
17+
18+
route.HandleFunc("/register", RenderRegister)
19+
20+
route.HandleFunc("/signin", SignInUser).Methods("POST")
21+
22+
route.HandleFunc("/signup", SignUpUser).Methods("POST")
23+
24+
route.HandleFunc("/userDetails", GetUserDetails).Methods("GET")
25+
26+
log.Println("Routes are Loaded.")
27+
}

server.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package main
2+
3+
import (
4+
"log"
5+
"net/http"
6+
7+
"github.com/gorilla/mux"
8+
)
9+
10+
func main() {
11+
12+
log.Println("Server will start at http://localhost:8000/")
13+
14+
ConnectDatabase()
15+
16+
route := mux.NewRouter()
17+
18+
AddApproutes(route)
19+
20+
log.Fatal(http.ListenAndServe(":8000", route))
21+
}

0 commit comments

Comments
 (0)