fullstack web app-golang #2

f

So basically we did everything except database stuffs in previous article. so let’s add database to the server.

First lets connect our mongodb to our app.

In db/connect.go.

package db

import (
	"context"
	"fmt"
	"log"

	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

//connect to mongo

// Set client options
var clientOptions = options.Client().ApplyURI("mongodb://localhost:27017")

// Connect to MongoDB
var Client, err = mongo.Connect(context.TODO(), clientOptions)

//choose your collection
//var collection = client.Database("webapp").Collection("user")

func Connectmongo() {
	if err != nil {
		log.Fatal(err)
	}

	// Check the connection
	err = Client.Ping(context.TODO(), nil)

	if err != nil {
		log.Fatal(err)
	}

	fmt.Println("Connected to MongoDB!")
}

Now in our main file use this:


func main() {
	//connect to db
	db.Connectmongo()

	// Init router
	r := mux.NewRouter()

	r.HandleFunc("/register", helpers.SaveUser).Methods("POST")
	r.HandleFunc("/login", helpers.FindUser).Methods("POST")

	//start the server
	log.Fatal(http.ListenAndServe(":8080", c.Handler(r)))

}

Now in the db/userHandler.go, lets write some helping functions:

package db

import (
	"context"
	"fmt"
	"log"
	"web-app/model"
	"go.mongodb.org/mongo-driver/bson"
)

var collection = Client.Database("webapp").Collection("user")

func AddUser(regObj model.Register) {
	//insert the user
	user := model.User{}
	user.Name = regObj.Name
	user.Email = regObj.Email
	user.Password = regObj.Password

	insertResult, err := collection.InsertOne(context.TODO(), user)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println("Inserted a single document: ", insertResult.InsertedID)
}

func FindUserdb(email string) model.User{

	filter := bson.D{{"email", email}}
	var res = model.User{}

	err = collection.FindOne(context.TODO(), filter).Decode(&res)
	if err != nil {
	//	log.Fatal(err)
		return model.User{}
	}

	fmt.Printf("Found a single document: %+v\n", res)
	return res
}
  • AddUser() is used to add a user to the db
  • findUser() is used to find the user in the db

Now lets complete our routes.go

for saveuser()

  • decode the request body
  • check if user exists
  • hash the password
  • save it to db
  • generate jwt
  • send that jwt

//SaveUser is for '/register' post
func SaveUser(w http.ResponseWriter, r *http.Request) {
       decoder := json.NewDecoder(r.Body)

	var t model.Register
	err := decoder.Decode(&t)
	if err != nil {
		panic(err)
	}

	fmt.Println(t)

	//check if the user already register
	user := db.FindUserdb(t.Email)

	if user.Email != "" {
		json.NewEncoder(w).Encode("user already exists")
		return
	}

	//hash the password
	hashedPassword, err := bcrypt.GenerateFromPassword([]byte(t.Password), bcrypt.DefaultCost)
	if err != nil {
		panic(err)
	}
	t.Password = string(hashedPassword)

	//save it to DB
	db.AddUser(t)

	//generate jwt and send it
	token, err := GenerateJWT(t.Email)

	if err != nil {
		fmt.Println("Failed to generate token")
	}

	json.NewEncoder(w).Encode(token)

}

for finduser()

  • decode the request body
  • find user in the db
  • check if user exists
  • compare the password
  • send jwt

func FindUser(w http.ResponseWriter, r *http.Request) {

	decoder := json.NewDecoder(r.Body)

	var t model.Login
	err := decoder.Decode(&t)
	if err != nil {
		panic(err)
	}

	fmt.Println(t)

	//find it in the db

	user := db.FindUserdb(t.Email)
	fmt.Println(user.Email)

	//check if the user exists
	if user.Email == "" {
		json.NewEncoder(w).Encode("can't find the user")
		return
	}

	err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(t.Password))

	if err != nil {
		//incorrect password
		json.NewEncoder(w).Encode("incorrect password")
		return
	}
	//generate jwt and send it
	token, err := GenerateJWT(t.Email)

	if err != nil {
		fmt.Println("Failed to generate token")
	}

	json.NewEncoder(w).Encode(token)

}

Now lets check whether this works.

At first our db looks empty.

Now lets try to add a user.

we got the token and indeed a new user is created.

And if we tried to create the user with already existing email address,

So looks like its working.

Now lets test the login too.

And when we type the wrong password,

And for non-registered user,

So now we successfully builded our own authentication with mongodb as our database

Now lets finish the backend in our next article.

About the author

vigneshwar

Add comment

Leave a Reply

By vigneshwar

Most common tags

%d bloggers like this: