Register and Login Authentication With golang and gin gonic using mysql database and jwt Authentication

 main.go


package main

//cd "C:\Users\hp word\Desktop\go-workspace\src\Gin_Gonic_web_Reg"
// go run main.go
import (
    "database/sql"
    "strconv"
    "time"

    "github.com/gin-gonic/gin"

    "net/http"

    "github.com/dgrijalva/jwt-go"

    _ "github.com/go-sql-driver/mysql"
)

type Person struct {
    Id         int    `json:id`
    Name       string `json:name`
    Email      string `json:email`
    Password   string `json:password`
    Location   string `json:location`
    Department string `json:department`
    Income     int    `json:Income`
}

//CREATE JWT SECRET KEY THAT ARE USED TO SIGN OUR JWT TOKEN
var jwtKey = []byte("secret_key")

// //HERE WE ALSO USED DATABASE
// var users = map[string]string{
//  "user1": "password1",
//  "user2": "password2",
// }

// //VIA THIS WE CAN PASS DATA THROUGH API
// type Credentials struct {
//  Username string `json:"username"`
//  Password string `json:"password"`
// }

//CLAIMS ARE USING TO CREATE  PAYLOAD OF OUR JWT
//INSIDE THE PAYLOAD WE HAVE PASSING THE USER NAME AND WHEN THE PARTICULAR TOKEN IS EXPIRING
type Claims struct {
    Username string `json:"username"`
    jwt.StandardClaims
}

func dbConn() (db *sql.DB) {
    dbDriver := "mysql"
    dbUser := "root"
    dbPass := "root"
    dbName := "Employee_auth"
    db, err := sql.Open(dbDriver, dbUser+":"+dbPass+"@/"+dbName)
    if err != nil {
        panic(err.Error())
    }
    return db
}
func main() {
    router := gin.Default()
    router.LoadHTMLGlob("templates/*.html")
    //new template engine

    router.GET("/", func(ctx *gin.Context) {
        //render only file, must full name with extension
        db := dbConn()
        sd, err := db.Query("SELECT * FROM Person ORDER BY id DESC")
        if err != nil {
            panic(err.Error())
        }
        emp := Person{}
        res := []Person{}
        for sd.Next() {
            var id, income int
            var name, email, password, location, department string
            err = sd.Scan(&id, &name, &email, &password, &location, &department, &income)
            if err != nil {
                panic(err.Error())
            }
            emp.Id = id
            emp.Name = name
            emp.Email = email
            emp.Location = location
            emp.Department = department
            emp.Income = income
            res = append(res, emp)
        }
        //var a = "hello words"

        // COOKIE CODE
        // GET THE COOKIE FROM REQUEST
        cookie, err := ctx.Request.Cookie("token")
        if err != nil {
            if err == http.ErrNoCookie {
                // ctx.Writer.WriteHeader(http.StatusUnauthorized)
                ctx.HTML(http.StatusOK, "login.html", gin.H{"title": "index file title!!"})
                return
            }
            //ctx.Writer.WriteHeader(http.StatusBadRequest)
            ctx.HTML(http.StatusOK, "login.html", gin.H{"title": "index file title!!"})
            return
        }

        // GET THE VALUE OF THE TOKEN
        tokenStr := cookie.Value

        // CREATE THE  REFERENCE OF CLAIMS
        claims := &Claims{}

        // PARSE WITH CLAIMS AND GET THE TOKEN
        tkn, err := jwt.ParseWithClaims(tokenStr, claims,
            func(t *jwt.Token) (interface{}, error) {
                return jwtKey, nil
            })

        if err != nil {
            if err == jwt.ErrSignatureInvalid {
                //ctx.Writer.WriteHeader(http.StatusUnauthorized)
                ctx.HTML(http.StatusOK, "login.html", gin.H{"title": "index file title!!"})
                return
            }
            //ctx.Writer.WriteHeader(http.StatusBadRequest)
            ctx.HTML(http.StatusOK, "login.html", gin.H{"title": "index file title!!"})
            return
        }

        if !tkn.Valid {
            //ctx.Writer.WriteHeader(http.StatusUnauthorized)
            ctx.HTML(http.StatusOK, "login.html", gin.H{"title": "index file title!!"})
            return
        }

        // COOKIE CODE END HERE
        //  IF ALL THINGS ARE CORRECT THEN PRINT THEM
        //ctx.Writer.Write([]byte(fmt.Sprintf("Hello, %s", claims.Username)))
        ctx.HTML(http.StatusOK, "index.html", gin.H{"title": "index file title!!", "a": res})
    })

    router.GET("/about", func(ctx *gin.Context) {
        //render only file, must full name with extension
        ctx.HTML(http.StatusOK, "about.html", gin.H{"title": "index file title!!"})
    })

    router.GET("/contact", func(ctx *gin.Context) {
        //render only file, must full name with extension
        ctx.HTML(http.StatusOK, "contact.html", gin.H{"title": "index file title!!"})
    })

    // router.GET("/addnew", func(ctx *gin.Context) {
    //  //render only file, must full name with extension
    //  ctx.HTML(http.StatusOK, "addnew.html", gin.H{"title": "index file title!!"})
    // })
    router.GET("/registration", func(ctx *gin.Context) {
        //render only file, must full name with extension
        ctx.HTML(http.StatusOK, "registration.html", gin.H{"title": "index file title!!"})
    })

    router.GET("/login", func(ctx *gin.Context) {
        //render only file, must full name with extension
        ctx.HTML(http.StatusOK, "login.html", gin.H{"title": "index file title!!"})
    })

    router.GET("/submit", func(ctx *gin.Context) {
        //render only file, must full name with extension
        var name, email, password, location, department string
        var income int

        name = ctx.Request.FormValue("name")
        email = ctx.Request.FormValue("email")
        password = ctx.Request.FormValue("password")
        location = ctx.Request.FormValue("location")
        department = ctx.Request.FormValue("department")

        sal := ctx.Request.FormValue("income")
        income, _ = strconv.Atoi(sal)
        db := dbConn()
        insForm, err := db.Prepare("INSERT INTO Person(name,email,password, location, department, income) VALUES(?,?,?,?,?,?)")
        if err != nil {
            panic(err.Error())
        }
        insForm.Exec(name, email, password, location, department, income)

        sd, err := db.Query("SELECT * FROM Person ORDER BY id DESC")
        if err != nil {
            panic(err.Error())
        }
        emp := Person{}
        res := []Person{}
        for sd.Next() {
            var id, income int
            var name, email, password, location, department string
            err = sd.Scan(&id, &name, &email, &password, &location, &department, &income)
            if err != nil {
                panic(err.Error())
            }
            emp.Id = id
            emp.Name = name
            emp.Email = email
            //emp.Name = name
            emp.Location = location
            emp.Department = department
            emp.Income = income
            res = append(res, emp)
        }

        // COOKIE CODE
        // GET THE COOKIE FROM REQUEST
        cookie, err := ctx.Request.Cookie("token")
        if err != nil {
            if err == http.ErrNoCookie {
                // ctx.Writer.WriteHeader(http.StatusUnauthorized)
                ctx.HTML(http.StatusOK, "login.html", gin.H{"title": "index file title!!"})
                return
            }
            //ctx.Writer.WriteHeader(http.StatusBadRequest)
            ctx.HTML(http.StatusOK, "login.html", gin.H{"title": "index file title!!"})
            return
        }

        // GET THE VALUE OF THE TOKEN
        tokenStr := cookie.Value

        // CREATE THE  REFERENCE OF CLAIMS
        claims := &Claims{}

        // PARSE WITH CLAIMS AND GET THE TOKEN
        tkn, err := jwt.ParseWithClaims(tokenStr, claims,
            func(t *jwt.Token) (interface{}, error) {
                return jwtKey, nil
            })

        if err != nil {
            if err == jwt.ErrSignatureInvalid {
                //ctx.Writer.WriteHeader(http.StatusUnauthorized)
                ctx.HTML(http.StatusOK, "login.html", gin.H{"title": "index file title!!"})
                return
            }
            //ctx.Writer.WriteHeader(http.StatusBadRequest)
            ctx.HTML(http.StatusOK, "login.html", gin.H{"title": "index file title!!"})
            return
        }

        if !tkn.Valid {
            //ctx.Writer.WriteHeader(http.StatusUnauthorized)
            ctx.HTML(http.StatusOK, "login.html", gin.H{"title": "index file title!!"})
            return
        }

        // COOKIE CODE END HERE
        ctx.HTML(http.StatusOK, "index.html", gin.H{"title": "index file title!!", "a": res})
    })

    router.GET("/submitforlogin", func(ctx *gin.Context) {
        //render only file, must full name with extension
        // var name, location, department string
        // var income int
        var email, password string

        email = ctx.Request.FormValue("email")
        password = ctx.Request.FormValue("password")
        // department = ctx.Request.FormValue("department")

        // sal := ctx.Request.FormValue("income")
        // income, _ = strconv.Atoi(sal)
        db := dbConn()
        // insForm, err := db.Prepare("INSERT INTO Person(name, location, department, income) VALUES(?,?,?,?)")
        // if err != nil {
        //  panic(err.Error())
        // }
        // insForm.Exec(name, location, department, income)

        sd, err := db.Query("SELECT * FROM Person")
        if err != nil {
            panic(err.Error())
        }
        emp := Person{}
        res := []Person{}
        var list_emp = make(map[string]string)
        for sd.Next() {
            var id, income int
            var name, email, password, location, department string
            err = sd.Scan(&id, &name, &email, &password, &location, &department, &income)
            if err != nil {
                panic(err.Error())
            }
            emp.Id = id
            emp.Name = name
            emp.Email = email
            emp.Location = location
            emp.Department = department
            emp.Income = income
            list_emp[email] = password
            res = append(res, emp)
        }
        // CHECK EXPECTED USER PRESENT IN OUR MAP( OR DATABASE )
        expectedPassword, ok := list_emp[email]

        if !ok || expectedPassword != password {
            ctx.Writer.WriteHeader(http.StatusUnauthorized)
            return
        }

        // THIS IS EXPIRATION TIME OF OUR TOKEN
        expirationTime := time.Now().Add(time.Minute * 1)

        // CREATE CLAIMS FOR OUR TOKEN
        claims := &Claims{
            Username: email,
            StandardClaims: jwt.StandardClaims{
                ExpiresAt: expirationTime.Unix(),
            },
        }

        // CREATE TOKEN
        // HERE WE HS 256 ALGORITHM FOR SIGNING IN
        token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

        // GET THE TOKEN STRING FROM THE TOKEN
        tokenString, err := token.SignedString(jwtKey)

        if err != nil {
            ctx.Writer.WriteHeader(http.StatusInternalServerError)
            return
        }

        // SET ABOVE THING INTO OUR COOKIES
        http.SetCookie(ctx.Writer,
            &http.Cookie{
                Name:    "token",
                Value:   tokenString,
                Expires: expirationTime,
            })

        ctx.HTML(http.StatusOK, "index.html", gin.H{"title": "index file title!!", "a": res})
    })

    router.Run(":9090")
}


templates/index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Kloudone</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>

<nav class="navbar navbar-inverse">
  <div class="container-fluid">
    <div class="navbar-header">
      <a class="navbar-brand" href="#">KloudOne - Cloud engineering and migration services</a>
    </div>
    <ul class="nav navbar-nav">
      <li class="active"><a href="#">Home</a></li>
      <li><a href="/about">About</a></li>
      <li><a href="/contact">Contact</a></li>
      
    </ul>
  </div>

</nav>
  
<div class="container">
  
  <h2>Welcome to Kloudone</h2>
  <h3>This is a home page.</h3>
</div>
 <h2> Registered Employers </h2>
    <table class="table">
      <thead class="thead-dark">
      <tr>
        <td>ID</td>
        <td>Name</td>
        <td>Email</td>

        <td>Location</td>
        <td>Department</td>
        <td>Income</td>
      </tr>
       </thead>
       <tbody>
    {{ range .a }}
      <tr>
        <td>{{ .Id }}</td>
        <td> {{ .Name }} </td>
        <td> {{ .Email }} </td>
        <td>{{ .Location }} </td>
        <td>{{ .Department }} </td>
        <td>{{ .Income }} </td> 
      </tr>
    {{ end }}
       </tbody>
    </table>
    <center>
    <h2><a href="/registration">Register </a></h2></center>
</body>
</html>




templates/register.html

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {
  font-family: Arial, Helvetica, sans-serif;
  background-color: black;
}

* {
  box-sizing: border-box;
}

/* Add padding to containers */
.container {
  padding: 16px;
  background-color: white;
}

/* Full-width input fields */
input[type=text], input[type=password] {
  width: 100%;
  padding: 15px;
  margin: 5px 0 22px 0;
  display: inline-block;
  border: none;
  background: #f1f1f1;
}

input[type=text]:focus, input[type=password]:focus {
  background-color: #ddd;
  outline: none;
}

/* Overwrite default styles of hr */
hr {
  border: 1px solid #f1f1f1;
  margin-bottom: 25px;
}

/* Set a style for the submit button */
.registerbtn {
  background-color: #4CAF50;
  color: white;
  padding: 16px 20px;
  margin: 8px 0;
  border: none;
  cursor: pointer;
  width: 100%;
  opacity: 0.9;
}

.registerbtn:hover {
  opacity: 1;
}

/* Add a blue text color to links */
a {
  color: dodgerblue;
}

/* Set a grey background color and center the text of the "sign in" section */
.signin {
  background-color: #f1f1f1;
  text-align: center;
}
</style>
</head>
<body>


    <!-- <center>
        <form method="GET" action="submit">
              <label> Name </label><input type="text" name="name" id="name"/><br />
              <label> Location </label><input type="text" name="location" id="location"/><br />
              <label> Department </label><input type="text" name="department" id="department"/><br />
              <label> Income </label><input type="text" name="income" id="income"/><br />
        
            
              <input type="submit">
            </form>
        </center>     -->
<form method="GET" action="submit">
  <div class="container">
    <h1>Register</h1>
    <p>Please fill in this form to create an account.</p>
    <hr>

    <label ><b>Name </b></label>
    <input type="text" placeholder="Enter name" name="name" id="name" required>

    <label ><b>Email </b></label>
    <input type="text" placeholder="Enter email id" name="email" id="email" required>

    <label ><b>Password </b></label>
    <input type="password" placeholder="Enter password" name="password" id="password" required>

    <label ><b>Location</b></label>
    <input type="text" placeholder="Enter Location" name="location" id="location" required>

    <label ><b>Department</b></label>
    <input type="text" placeholder="Enter Department" name="department" id="department" required>
    <label ><b>Income</b></label>
    <input type="text" placeholder="Enter Income" name="income" id="income" required>

    <hr>
    <p>By creating an account you agree to our <a href="#">Terms & Privacy</a>.</p>

    <!-- <button type="submit" class="registerbtn">Register</button> -->
    <input type="submit"  class="registerbtn">
  </div>
  
  <div class="container signin">
    <p>Already have an account? <a href="login">Sign in</a>.</p>
  </div>
</form>

</body>
</html>




templates/login.html


<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {
  font-family: Arial, Helvetica, sans-serif;
  background-color: black;
}

* {
  box-sizing: border-box;
}

/* Add padding to containers */
.container {
  padding: 16px;
  background-color: white;
}

/* Full-width input fields */
input[type=text], input[type=password] {
  width: 100%;
  padding: 15px;
  margin: 5px 0 22px 0;
  display: inline-block;
  border: none;
  background: #f1f1f1;
}

input[type=text]:focus, input[type=password]:focus {
  background-color: #ddd;
  outline: none;
}

/* Overwrite default styles of hr */
hr {
  border: 1px solid #f1f1f1;
  margin-bottom: 25px;
}

/* Set a style for the submit button */
.registerbtn {
  background-color: #4CAF50;
  color: white;
  padding: 16px 20px;
  margin: 8px 0;
  border: none;
  cursor: pointer;
  width: 100%;
  opacity: 0.9;
}

.registerbtn:hover {
  opacity: 1;
}

/* Add a blue text color to links */
a {
  color: dodgerblue;
}

/* Set a grey background color and center the text of the "sign in" section */
.signin {
  background-color: #f1f1f1;
  text-align: center;
}
</style>
</head>
<body>


   
<form method="GET" action="submitforlogin">
  <div class="container">
    <h1>Log in</h1>
    <p>Please login first.</p>
    <hr>

    <label ><b>Email </b></label>
    <input type="text" placeholder="Enter email" name="email" id="email" required>

    <label ><b>Password</b></label>
    <input type="password" placeholder="Enter password" name="password" id="password" required>

    <!-- <label ><b>Department</b></label>
    <input type="text" placeholder="Enter Department" name="department" id="department" required>
    <label ><b>Income</b></label>
    <input type="text" placeholder="Enter Income" name="income" id="income" required> -->

    <hr>
    <p>By login you access home page <a href="#">Terms & Privacy</a>.</p>

    <!-- <button type="submit" class="registerbtn">Register</button> -->
    <input type="submit"  class="registerbtn">
  </div>
  
  <div class="container signin">
    <p>Not have an account? <a href="registration">Register</a>.</p>
  </div>
</form>

</body>
</html>



Comments