Browse Source

try 1

master
Nicolas Dinquel 6 years ago
parent
commit
f70caf557c
  1. 7
      .env
  2. 79
      app/auth.go
  3. 15
      app/errors.go
  4. 0
      controllers/authController.go
  5. 0
      controllers/contactsController.go
  6. 27
      main.go
  7. 41
      models/base.go
  8. 15
      utils/utils.go

7
.env

@ -0,0 +1,7 @@
db_name = gocontacts
db_pass = password
db_user = postgres
db_type = postgres
db_host = localhost
db_port = 5434
token_password = thisIsTheJwtSecretPassword //Do not commit to git!

79
app/auth.go

@ -0,0 +1,79 @@
package app
import (
"net/http"
u "../utils"
"strings"
"../models"
jwt "github.com/dgrijalva/jwt-go"
"os"
"context"
"fmt"
)
var JwtAuthentication = func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
notAuth := []string{"/api/user/new", "/api/user/login"} //List of endpoints that doesn't require auth
requestPath := r.URL.Path //current request path
//check if request does not need authentication, serve the request if it doesn't need it
for _, value := range notAuth {
if value == requestPath {
next.ServeHTTP(w, r)
return
}
}
response := make(map[string] interface{})
tokenHeader := r.Header.Get("Authorization") //Grab the token from the header
if tokenHeader == "" { //Token is missing, returns with error code 403 Unauthorized
response = u.Message(false, "Missing auth token")
w.WriteHeader(http.StatusForbidden)
w.Header().Add("Content-Type", "application/json")
u.Respond(w, response)
return
}
splitted := strings.Split(tokenHeader, " ") //The token normally comes in format `Bearer {token-body}`, we check if the retrieved token matched this requirement
if len(splitted) != 2 {
response = u.Message(false, "Invalid/Malformed auth token")
w.WriteHeader(http.StatusForbidden)
w.Header().Add("Content-Type", "application/json")
u.Respond(w, response)
return
}
tokenPart := splitted[1] //Grab the token part, what we are truly interested in
tk := &models.Token{}
token, err := jwt.ParseWithClaims(tokenPart, tk, func(token *jwt.Token) (interface{}, error) {
return []byte(os.Getenv("token_password")), nil
})
if err != nil { //Malformed token, returns with http code 403 as usual
response = u.Message(false, "Malformed authentication token")
w.WriteHeader(http.StatusForbidden)
w.Header().Add("Content-Type", "application/json")
u.Respond(w, response)
return
}
if !token.Valid { //Token is invalid, maybe not signed on this server
response = u.Message(false, "Token is not valid.")
w.WriteHeader(http.StatusForbidden)
w.Header().Add("Content-Type", "application/json")
u.Respond(w, response)
return
}
//Everything went well, proceed with the request and set the caller to the user retrieved from the parsed token
fmt.Sprintf("User %", tk.Username) //Useful for monitoring
ctx := context.WithValue(r.Context(), "user", tk.UserId)
r = r.WithContext(ctx)
next.ServeHTTP(w, r) //proceed in the middleware chain!
});
}

15
app/errors.go

@ -0,0 +1,15 @@
package app
import (
"net/http"
u "../utils"
)
var NotFoundHandler = func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
u.Respond(w, u.Message(false, "This resources was not found on our server"))
next.ServeHTTP(w, r)
})
}

0
controllers/authController.go

0
controllers/contactsController.go

27
main.go

@ -0,0 +1,27 @@
package main
import (
"github.com/gorilla/mux"
"./app"
"os"
"fmt"
"net/http"
)
func main() {
router := mux.NewRouter()
router.Use(app.JwtAuthentication) //attach JWT auth middleware
port := os.Getenv("PORT") //Get port from .env file, we did not specify any port so this should return an empty string when tested locally
if port == "" {
port = "8000" //localhost
}
fmt.Println(port)
err := http.ListenAndServe(":" + port, router) //Launch the app, visit localhost:8000/api
if err != nil {
fmt.Print(err)
}
}

41
models/base.go

@ -0,0 +1,41 @@
package models
import (
_ "github.com/jinzhu/gorm/dialects/postgres"
"github.com/jinzhu/gorm"
"os"
"github.com/joho/godotenv"
"fmt"
)
var db *gorm.DB //database
func init() {
e := godotenv.Load() //Load .env file
if e != nil {
fmt.Print(e)
}
username := os.Getenv("db_user")
password := os.Getenv("db_pass")
dbName := os.Getenv("db_name")
dbHost := os.Getenv("db_host")
dbUri := fmt.Sprintf("host=%s user=%s dbname=%s sslmode=disable password=%s", dbHost, username, dbName, password) //Build connection string
fmt.Println(dbUri)
conn, err := gorm.Open("postgres", dbUri)
if err != nil {
fmt.Print(err)
}
db = conn
db.Debug().AutoMigrate(&Account{}, &Contact{}) //Database migration
}
//returns a handle to the DB object
func GetDB() *gorm.DB {
return db
}

15
utils/utils.go

@ -0,0 +1,15 @@
package utils
import (
"encoding/json"
"net/http"
)
func Message(status bool, message string) (map[string]interface{}) {
return map[string]interface{} {"status" : status, "message" : message}
}
func Respond(w http.ResponseWriter, data map[string] interface{}) {
w.Header().Add("Content-Type", "application/json")
json.NewEncoder(w).Encode(data)
}
Loading…
Cancel
Save