Merge branch 'cookie_auth' of Asara/sudoscientist-go-backend into master
This commit is contained in:
commit
2fb9ad73d5
6 changed files with 53 additions and 21 deletions
|
@ -66,7 +66,7 @@ Install steps are for Debian 9 (stretch)
|
||||||
|
|
||||||
5. Run the application!
|
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
|
for i in settings/*; do source $i; done
|
||||||
export DB_HOST=$(docker inspect -f "{{ .NetworkSettings.IPAddress }}" sudosci-db)
|
export DB_HOST=$(docker inspect -f "{{ .NetworkSettings.IPAddress }}" sudosci-db)
|
||||||
go get
|
go get
|
||||||
|
|
4
main.go
4
main.go
|
@ -56,6 +56,10 @@ func Routes() *chi.Mux {
|
||||||
// LOCK THIS DOWN FOR PRODUCTION
|
// LOCK THIS DOWN FOR PRODUCTION
|
||||||
cors := cors.New(cors.Options{
|
cors := cors.New(cors.Options{
|
||||||
AllowedOrigins: []string{"*"},
|
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(
|
router.Use(
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"git.minhas.io/asara/sudoscientist-go-backend/packages/middleware"
|
||||||
"git.minhas.io/asara/sudoscientist-go-backend/packages/users"
|
"git.minhas.io/asara/sudoscientist-go-backend/packages/users"
|
||||||
"github.com/badoux/checkmail"
|
"github.com/badoux/checkmail"
|
||||||
"github.com/dgrijalva/jwt-go"
|
"github.com/dgrijalva/jwt-go"
|
||||||
|
@ -12,6 +13,7 @@ import (
|
||||||
"github.com/go-chi/render"
|
"github.com/go-chi/render"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -53,7 +55,7 @@ func Routes() *chi.Mux {
|
||||||
r.Post("/signin", signin)
|
r.Post("/signin", signin)
|
||||||
r.Post("/register", register)
|
r.Post("/register", register)
|
||||||
r.Group(func(r chi.Router) {
|
r.Group(func(r chi.Router) {
|
||||||
r.Use(jwtauth.Verifier(TokenAuth))
|
r.Use(jwtauth.Verify(TokenAuth, auth_middleware.TokenFromSplitCookie))
|
||||||
r.Use(jwtauth.Authenticator)
|
r.Use(jwtauth.Authenticator)
|
||||||
r.Post("/refresh", refresh)
|
r.Post("/refresh", refresh)
|
||||||
})
|
})
|
||||||
|
@ -113,9 +115,8 @@ func register(w http.ResponseWriter, r *http.Request) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_, tokenString, _ := TokenAuth.Encode(claims)
|
_, tokenString, _ := TokenAuth.Encode(claims)
|
||||||
token := JWT{
|
token := setCookies(w, tokenString, expirationTime)
|
||||||
JWT: tokenString,
|
w.WriteHeader(http.StatusOK)
|
||||||
}
|
|
||||||
render.JSON(w, r, token)
|
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 {
|
if err = bcrypt.CompareHashAndPassword([]byte(storedCreds.Password), []byte(creds.Password)); err != nil {
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
}
|
}
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
expirationTime := time.Now().Add(5 * time.Hour)
|
expirationTime := time.Now().Add(5 * time.Hour)
|
||||||
claims := &Claims{
|
claims := &Claims{
|
||||||
Username: creds.Username,
|
Username: creds.Username,
|
||||||
|
@ -149,9 +149,8 @@ func signin(w http.ResponseWriter, r *http.Request) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_, tokenString, _ := TokenAuth.Encode(claims)
|
_, tokenString, _ := TokenAuth.Encode(claims)
|
||||||
token := JWT{
|
token := setCookies(w, tokenString, expirationTime)
|
||||||
JWT: tokenString,
|
w.WriteHeader(http.StatusOK)
|
||||||
}
|
|
||||||
render.JSON(w, r, token)
|
render.JSON(w, r, token)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,8 +165,16 @@ func refresh(w http.ResponseWriter, r *http.Request) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_, tokenString, _ := TokenAuth.Encode(newClaims)
|
_, tokenString, _ := TokenAuth.Encode(newClaims)
|
||||||
token := JWT{
|
token := setCookies(w, tokenString, expirationTime)
|
||||||
JWT: tokenString,
|
w.WriteHeader(http.StatusOK)
|
||||||
}
|
|
||||||
render.JSON(w, r, token)
|
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], ".")
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"git.minhas.io/asara/sudoscientist-go-backend/packages/middleware"
|
||||||
"github.com/go-chi/chi"
|
"github.com/go-chi/chi"
|
||||||
"github.com/go-chi/jwtauth"
|
"github.com/go-chi/jwtauth"
|
||||||
"github.com/go-chi/render"
|
"github.com/go-chi/render"
|
||||||
|
@ -79,13 +80,13 @@ func Init() {
|
||||||
func Routes() *chi.Mux {
|
func Routes() *chi.Mux {
|
||||||
r := chi.NewRouter()
|
r := chi.NewRouter()
|
||||||
r.Group(func(r chi.Router) {
|
r.Group(func(r chi.Router) {
|
||||||
r.Use(jwtauth.Verifier(TokenAuth))
|
r.Use(jwtauth.Verify(TokenAuth, auth_middleware.TokenFromSplitCookie))
|
||||||
r.Use(jwtauth.Authenticator)
|
r.Use(jwtauth.Authenticator)
|
||||||
r.Post("/", createBlogPost)
|
r.Post("/", createBlogPost)
|
||||||
r.Patch("/by-id/{id}", updateBlogPostById)
|
r.Patch("/by-id/{id}", updateBlogPostById)
|
||||||
|
r.Get("/by-slug/{slug}", getBlogPostBySlug)
|
||||||
})
|
})
|
||||||
r.Get("/", getBlogPosts)
|
r.Get("/", getBlogPosts)
|
||||||
r.Get("/by-slug/{slug}", getBlogPostBySlug)
|
|
||||||
r.Get("/by-id/{id}", getBlogPostById)
|
r.Get("/by-id/{id}", getBlogPostById)
|
||||||
r.Get("/by-tag/{tag}", getBlogPostsByTag)
|
r.Get("/by-tag/{tag}", getBlogPostsByTag)
|
||||||
r.Get("/by-author/{author}", getBlogPostsByAuthor)
|
r.Get("/by-author/{author}", getBlogPostsByAuthor)
|
||||||
|
|
19
packages/middleware/auth_middleware.go
Normal file
19
packages/middleware/auth_middleware.go
Normal file
|
@ -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
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"git.minhas.io/asara/sudoscientist-go-backend/packages/middleware"
|
||||||
"github.com/go-chi/chi"
|
"github.com/go-chi/chi"
|
||||||
"github.com/go-chi/jwtauth"
|
"github.com/go-chi/jwtauth"
|
||||||
"github.com/go-chi/render"
|
"github.com/go-chi/render"
|
||||||
|
@ -36,7 +37,7 @@ func Init() {
|
||||||
func Routes() *chi.Mux {
|
func Routes() *chi.Mux {
|
||||||
r := chi.NewRouter()
|
r := chi.NewRouter()
|
||||||
r.Group(func(r chi.Router) {
|
r.Group(func(r chi.Router) {
|
||||||
r.Use(jwtauth.Verifier(TokenAuth))
|
r.Use(jwtauth.Verify(TokenAuth, auth_middleware.TokenFromSplitCookie))
|
||||||
r.Use(jwtauth.Authenticator)
|
r.Use(jwtauth.Authenticator)
|
||||||
r.Put("/{username}", updateUser)
|
r.Put("/{username}", updateUser)
|
||||||
})
|
})
|
||||||
|
|
Reference in a new issue