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
Post a Comment