diff --git a/README.md b/README.md index 6dbf687..b1e58c9 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ Install steps are for Debian 9 (stretch) 5. Run the application! ``` - cd ${GOPATH}/src/git.minhas.io/asara/sudoscientist + cd ${GOPATH}/src/git.minhas.io/asara/sudoscientist-go-backend for i in settings/*; do source $i; done export DB_HOST=$(docker inspect -f "{{ .NetworkSettings.IPAddress }}" sudosci-db) go get diff --git a/main.go b/main.go index 3a597a8..8af50a6 100644 --- a/main.go +++ b/main.go @@ -52,14 +52,18 @@ func main() { func Routes() *chi.Mux { router := chi.NewRouter() - // enable cors testing - // LOCK THIS DOWN FOR PRODUCTION - cors := cors.New(cors.Options{ - AllowedOrigins: []string{"*"}, - }) + // enable cors testing + // LOCK THIS DOWN FOR PRODUCTION + cors := cors.New(cors.Options{ + AllowedOrigins: []string{"*"}, + AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"}, + AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token"}, + AllowCredentials: true, + MaxAge: 360, + }) router.Use( - cors.Handler, + cors.Handler, render.SetContentType(render.ContentTypeJSON), middleware.Logger, middleware.DefaultCompress, diff --git a/packages/auth/auth.go b/packages/auth/auth.go index 5e29eb3..a73e6a6 100644 --- a/packages/auth/auth.go +++ b/packages/auth/auth.go @@ -4,6 +4,7 @@ import ( "database/sql" "encoding/json" "fmt" + "git.minhas.io/asara/sudoscientist-go-backend/packages/middleware" "git.minhas.io/asara/sudoscientist-go-backend/packages/users" "github.com/badoux/checkmail" "github.com/dgrijalva/jwt-go" @@ -12,6 +13,7 @@ import ( "github.com/go-chi/render" "golang.org/x/crypto/bcrypt" "net/http" + "strings" "time" ) @@ -53,7 +55,7 @@ func Routes() *chi.Mux { r.Post("/signin", signin) r.Post("/register", register) r.Group(func(r chi.Router) { - r.Use(jwtauth.Verifier(TokenAuth)) + r.Use(jwtauth.Verify(TokenAuth, auth_middleware.TokenFromSplitCookie)) r.Use(jwtauth.Authenticator) r.Post("/refresh", refresh) }) @@ -113,9 +115,8 @@ func register(w http.ResponseWriter, r *http.Request) { }, } _, tokenString, _ := TokenAuth.Encode(claims) - token := JWT{ - JWT: tokenString, - } + token := setCookies(w, tokenString, expirationTime) + w.WriteHeader(http.StatusOK) render.JSON(w, r, token) } @@ -140,7 +141,6 @@ func signin(w http.ResponseWriter, r *http.Request) { if err = bcrypt.CompareHashAndPassword([]byte(storedCreds.Password), []byte(creds.Password)); err != nil { w.WriteHeader(http.StatusUnauthorized) } - w.WriteHeader(http.StatusOK) expirationTime := time.Now().Add(5 * time.Hour) claims := &Claims{ Username: creds.Username, @@ -149,9 +149,8 @@ func signin(w http.ResponseWriter, r *http.Request) { }, } _, tokenString, _ := TokenAuth.Encode(claims) - token := JWT{ - JWT: tokenString, - } + token := setCookies(w, tokenString, expirationTime) + w.WriteHeader(http.StatusOK) render.JSON(w, r, token) } @@ -166,8 +165,16 @@ func refresh(w http.ResponseWriter, r *http.Request) { }, } _, tokenString, _ := TokenAuth.Encode(newClaims) - token := JWT{ - JWT: tokenString, - } + token := setCookies(w, tokenString, expirationTime) + w.WriteHeader(http.StatusOK) render.JSON(w, r, token) } + +func setCookies(w http.ResponseWriter, jwt string, expiration time.Time) string { + splitToken := strings.Split(jwt, ".") + dataCookie := http.Cookie{Name: "DataCookie", Value: strings.Join(splitToken[:2], "."), Expires: expiration, HttpOnly: false, Path: "/", Domain: ".sudosci.test", MaxAge: 360, Secure: false} + http.SetCookie(w, &dataCookie) + signatureCookie := http.Cookie{Name: "SignatureCookie", Value: splitToken[2], Expires: expiration, HttpOnly: true, Path: "/", Domain: ".sudosci.test", MaxAge: 360, Secure: false} + http.SetCookie(w, &signatureCookie) + return strings.Join(splitToken[:2], ".") +} diff --git a/packages/blog/blog.go b/packages/blog/blog.go index d8a2c23..640e30b 100644 --- a/packages/blog/blog.go +++ b/packages/blog/blog.go @@ -4,6 +4,7 @@ import ( "database/sql" "encoding/json" "fmt" + "git.minhas.io/asara/sudoscientist-go-backend/packages/middleware" "github.com/go-chi/chi" "github.com/go-chi/jwtauth" "github.com/go-chi/render" @@ -79,13 +80,13 @@ func Init() { func Routes() *chi.Mux { r := chi.NewRouter() r.Group(func(r chi.Router) { - r.Use(jwtauth.Verifier(TokenAuth)) + r.Use(jwtauth.Verify(TokenAuth, auth_middleware.TokenFromSplitCookie)) r.Use(jwtauth.Authenticator) r.Post("/", createBlogPost) r.Patch("/by-id/{id}", updateBlogPostById) + r.Get("/by-slug/{slug}", getBlogPostBySlug) }) r.Get("/", getBlogPosts) - r.Get("/by-slug/{slug}", getBlogPostBySlug) r.Get("/by-id/{id}", getBlogPostById) r.Get("/by-tag/{tag}", getBlogPostsByTag) r.Get("/by-author/{author}", getBlogPostsByAuthor) diff --git a/packages/middleware/auth_middleware.go b/packages/middleware/auth_middleware.go new file mode 100644 index 0000000..2d62a95 --- /dev/null +++ b/packages/middleware/auth_middleware.go @@ -0,0 +1,19 @@ +package auth_middleware + +import ( + "fmt" + "net/http" +) + +func TokenFromSplitCookie(r *http.Request) string { + dataCookie, err := r.Cookie("DataCookie") + if err != nil { + return "" + } + signatureCookie, err := r.Cookie("SignatureCookie") + if err != nil { + return "" + } + cookie := dataCookie.Value + "." + signatureCookie.Value + return cookie +} diff --git a/packages/users/users.go b/packages/users/users.go index 581ae46..a1aa6c6 100644 --- a/packages/users/users.go +++ b/packages/users/users.go @@ -4,6 +4,7 @@ import ( "database/sql" "encoding/json" "fmt" + "git.minhas.io/asara/sudoscientist-go-backend/packages/middleware" "github.com/go-chi/chi" "github.com/go-chi/jwtauth" "github.com/go-chi/render" @@ -36,7 +37,7 @@ func Init() { func Routes() *chi.Mux { r := chi.NewRouter() r.Group(func(r chi.Router) { - r.Use(jwtauth.Verifier(TokenAuth)) + r.Use(jwtauth.Verify(TokenAuth, auth_middleware.TokenFromSplitCookie)) r.Use(jwtauth.Authenticator) r.Put("/{username}", updateUser) })