Working login, register, logout
This commit is contained in:
parent
ec708a7723
commit
96e884f0a2
|
@ -9,7 +9,7 @@ services:
|
||||||
- POSTGRES_DB=auth
|
- POSTGRES_DB=auth
|
||||||
|
|
||||||
auth-api-db-migrate:
|
auth-api-db-migrate:
|
||||||
image: lilleman/auth-api-db-migrate:0.3.3
|
image: lilleman/auth-api-db-migrate:0.3.7
|
||||||
environment:
|
environment:
|
||||||
- DATABASE_URL=postgres://postgres:postgres@postgres:5432/auth?sslmode=disable
|
- DATABASE_URL=postgres://postgres:postgres@postgres:5432/auth?sslmode=disable
|
||||||
command: ["--wait", "up"]
|
command: ["--wait", "up"]
|
||||||
|
@ -18,7 +18,7 @@ services:
|
||||||
- postgres
|
- postgres
|
||||||
|
|
||||||
auth-api:
|
auth-api:
|
||||||
image: lilleman/auth-api:0.3.3
|
image: lilleman/auth-api:0.3.7
|
||||||
environment:
|
environment:
|
||||||
- ADMIN_API_KEY=hihi
|
- ADMIN_API_KEY=hihi
|
||||||
- DATABASE_URL=postgres://postgres:postgres@postgres:5432/auth?sslmode=disable
|
- DATABASE_URL=postgres://postgres:postgres@postgres:5432/auth?sslmode=disable
|
||||||
|
|
|
@ -22,7 +22,7 @@ func (api Api) Call(method string, path string, payload []byte) (ApiRes, error)
|
||||||
|
|
||||||
req, err := http.NewRequest(method, api.URL+path, bytes.NewBuffer(payload))
|
req, err := http.NewRequest(method, api.URL+path, bytes.NewBuffer(payload))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
api.Log.Error("Could not create request", "method", method, "err", err.Error())
|
api.Log.Error("Could not create request", "method", method, "path", path, "err", err.Error())
|
||||||
return ApiRes{}, err
|
return ApiRes{}, err
|
||||||
}
|
}
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
@ -31,22 +31,22 @@ func (api Api) Call(method string, path string, payload []byte) (ApiRes, error)
|
||||||
httpClient := &http.Client{}
|
httpClient := &http.Client{}
|
||||||
res, err := httpClient.Do(req)
|
res, err := httpClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
api.Log.Error("Could not call backend API", "err", err.Error())
|
api.Log.Error("Could not call backend API", "method", method, "path", path, "err", err.Error())
|
||||||
return ApiRes{}, err
|
return ApiRes{}, err
|
||||||
}
|
}
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
|
|
||||||
api.Log.Debug(api.URL+path+" res status", "status", res.StatusCode)
|
api.Log.Debug("API call res status", "method", method, "path", path, "status", res.StatusCode)
|
||||||
respObj.StatusCode = res.StatusCode
|
respObj.StatusCode = res.StatusCode
|
||||||
|
|
||||||
if strconv.Itoa(res.StatusCode)[0:1] == "5" {
|
if strconv.Itoa(res.StatusCode)[0:1] == "5" {
|
||||||
api.Log.Error("API gave internal server error", "statusCode", res.StatusCode)
|
api.Log.Error("API gave internal server error", "method", method, "path", path, "statusCode", res.StatusCode)
|
||||||
return ApiRes{}, errors.New("API gave internal server error")
|
return ApiRes{}, errors.New("API gave internal server error")
|
||||||
}
|
}
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(res.Body)
|
body, err := ioutil.ReadAll(res.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
api.Log.Error("Could not read res body", "err", err.Error())
|
api.Log.Error("Could not read res body", "method", method, "path", path, "err", err.Error())
|
||||||
return ApiRes{}, err
|
return ApiRes{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,20 @@ type LoginUser struct {
|
||||||
// Index GET
|
// Index GET
|
||||||
func (h Handlers) Index(c *fiber.Ctx) error {
|
func (h Handlers) Index(c *fiber.Ctx) error {
|
||||||
c.Set(fiber.HeaderContentType, fiber.MIMETextHTML)
|
c.Set(fiber.HeaderContentType, fiber.MIMETextHTML)
|
||||||
return c.SendString(views.Index(views.IndexData{}))
|
|
||||||
|
user, userLoggedIn := c.Locals("user").(utils.AuthClaims)
|
||||||
|
if !userLoggedIn {
|
||||||
|
user = utils.AuthClaims{}
|
||||||
|
}
|
||||||
|
|
||||||
|
userData := views.UserData{
|
||||||
|
Name: user.AccountName,
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.SendString(views.Index(views.IndexData{
|
||||||
|
UserData: userData,
|
||||||
|
UserLoggedIn: userLoggedIn,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Index POST
|
// Index POST
|
||||||
|
@ -45,8 +58,6 @@ func (h Handlers) IndexPost(c *fiber.Ctx) error {
|
||||||
return c.Status(500).SendString(views.Error500())
|
return c.Status(500).SendString(views.Error500())
|
||||||
}
|
}
|
||||||
|
|
||||||
h.Log.Debug("API res status", "status", apiRes.StatusCode)
|
|
||||||
|
|
||||||
if apiRes.StatusCode == 200 {
|
if apiRes.StatusCode == 200 {
|
||||||
err = utils.SetTokenCookies(apiRes.Body, c, h.Log)
|
err = utils.SetTokenCookies(apiRes.Body, c, h.Log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -54,10 +65,15 @@ func (h Handlers) IndexPost(c *fiber.Ctx) error {
|
||||||
return c.Status(500).SendString(views.Error500())
|
return c.Status(500).SendString(views.Error500())
|
||||||
}
|
}
|
||||||
|
|
||||||
userToken := c.Cookies("userToken")
|
tokens, err := utils.ParseTokenApiResBody(apiRes.Body, h.Log)
|
||||||
parsed, err := utils.ParseAndValidateToken(userToken, h.Api.JwtSharedSecret, h.Log)
|
if err != nil {
|
||||||
|
return c.Status(500).SendString(views.Error500())
|
||||||
|
}
|
||||||
|
|
||||||
|
parsed, err := utils.ParseAndValidateToken(tokens.Jwt, h.Api.JwtSharedSecret, h.Log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.Log.Error("Could not parse and validate new user token after renewal", "err", err.Error())
|
h.Log.Error("Could not parse and validate new user token after renewal", "err", err.Error())
|
||||||
|
h.Log.Debug("Broken token", "tokens.Jwt", tokens.Jwt, "apiRes.Body", string(apiRes.Body))
|
||||||
return c.Status(500).SendString(views.Error500())
|
return c.Status(500).SendString(views.Error500())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,6 +82,7 @@ func (h Handlers) IndexPost(c *fiber.Ctx) error {
|
||||||
return c.SendString(views.Index(views.IndexData{
|
return c.SendString(views.Index(views.IndexData{
|
||||||
OkMsg: "User logged in!",
|
OkMsg: "User logged in!",
|
||||||
Title: "Dashboard",
|
Title: "Dashboard",
|
||||||
|
UserLoggedIn: true,
|
||||||
}))
|
}))
|
||||||
} else if strconv.Itoa(apiRes.StatusCode)[0:1] == "4" {
|
} else if strconv.Itoa(apiRes.StatusCode)[0:1] == "4" {
|
||||||
var jsonResp []api.ApiResError
|
var jsonResp []api.ApiResError
|
||||||
|
|
|
@ -2,6 +2,7 @@ package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"gitlab.larvit.se/power-plan/auth-ui/src/views"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Logout
|
// Logout
|
||||||
|
@ -10,6 +11,6 @@ func (h Handlers) LogoutPost(c *fiber.Ctx) error {
|
||||||
c.ClearCookie("renewalToken")
|
c.ClearCookie("renewalToken")
|
||||||
c.Locals("user", "")
|
c.Locals("user", "")
|
||||||
|
|
||||||
c.Redirect("/")
|
c.Set(fiber.HeaderContentType, fiber.MIMETextHTML)
|
||||||
return nil
|
return c.SendString(views.Logout())
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,8 @@ func (h Handlers) HandleCookieTokens(c *fiber.Ctx) error {
|
||||||
return c.Status(500).SendString(views.Error500())
|
return c.Status(500).SendString(views.Error500())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h.Log.Debug("Setting new token cookies from", "apiRes.Body", apiRes.Body)
|
||||||
|
|
||||||
err = utils.SetTokenCookies(apiRes.Body, c, h.Log)
|
err = utils.SetTokenCookies(apiRes.Body, c, h.Log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.Log.Error("Could not unmarshal body from auth API", "err", err.Error())
|
h.Log.Error("Could not unmarshal body from auth API", "err", err.Error())
|
||||||
|
|
|
@ -41,15 +41,15 @@ func GetLog() *zap.SugaredLogger {
|
||||||
return log
|
return log
|
||||||
}
|
}
|
||||||
|
|
||||||
type authClaims struct {
|
type AuthClaims struct {
|
||||||
jwt.StandardClaims
|
jwt.StandardClaims
|
||||||
AccountId string `json:"accountId"`
|
AccountId string `json:"accountId"`
|
||||||
AccountFields map[string][]string `json:"accountFields"`
|
AccountFields map[string][]string `json:"accountFields"`
|
||||||
AccountName string `json:"accountName"`
|
AccountName string `json:"accountName"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseAndValidateToken(token string, jwtSecret string, log *zap.SugaredLogger) (authClaims, error) {
|
func ParseAndValidateToken(token string, jwtSecret string, log *zap.SugaredLogger) (AuthClaims, error) {
|
||||||
var claims authClaims
|
var claims AuthClaims
|
||||||
|
|
||||||
_, err := jwt.ParseWithClaims(token, &claims, func(token *jwt.Token) (interface{}, error) {
|
_, err := jwt.ParseWithClaims(token, &claims, func(token *jwt.Token) (interface{}, error) {
|
||||||
_, ok := token.Method.(*jwt.SigningMethodHMAC)
|
_, ok := token.Method.(*jwt.SigningMethodHMAC)
|
||||||
|
@ -65,7 +65,7 @@ func ParseAndValidateToken(token string, jwtSecret string, log *zap.SugaredLogge
|
||||||
} else {
|
} else {
|
||||||
log.Error("could not parse token with claims", "err", err.Error())
|
log.Error("could not parse token with claims", "err", err.Error())
|
||||||
}
|
}
|
||||||
return authClaims{}, err
|
return AuthClaims{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return claims, nil
|
return claims, nil
|
||||||
|
@ -76,14 +76,25 @@ type AuthRes struct {
|
||||||
RenewalToken string `json:"renewalToken"`
|
RenewalToken string `json:"renewalToken"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetTokenCookies(apiResBody []byte, c *fiber.Ctx, log *zap.SugaredLogger) error {
|
func ParseTokenApiResBody(apiResBody []byte, log *zap.SugaredLogger) (AuthRes, error) {
|
||||||
var authRes AuthRes
|
var authRes AuthRes
|
||||||
err := json.Unmarshal(apiResBody, &authRes)
|
err := json.Unmarshal(apiResBody, &authRes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Could not unmarshal body from auth API", "err", err.Error())
|
log.Error("Could not unmarshal body from auth API", "err", err.Error())
|
||||||
|
return AuthRes{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return authRes, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetTokenCookies(apiResBody []byte, c *fiber.Ctx, log *zap.SugaredLogger) error {
|
||||||
|
authRes, err := ParseTokenApiResBody(apiResBody, log)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Debug("setting cookies", "userToken", authRes.Jwt, "len(renewalToken)", len(authRes.RenewalToken))
|
||||||
|
|
||||||
c.Cookie(&fiber.Cookie{
|
c.Cookie(&fiber.Cookie{
|
||||||
Name: "userToken",
|
Name: "userToken",
|
||||||
Value: authRes.Jwt,
|
Value: authRes.Jwt,
|
||||||
|
|
|
@ -23,12 +23,16 @@ func Index(data IndexData) string {
|
||||||
|
|
||||||
if data.UserLoggedIn {
|
if data.UserLoggedIn {
|
||||||
content = `
|
content = `
|
||||||
<h1 class="main-title">Welcome ` + data.UserData.Name + `</h1>`
|
<h1 class="main-title">Welcome ` + data.UserData.Name + `</h1>
|
||||||
|
<form method="post" action="/logout">
|
||||||
|
<button type="submit">Logout</button>
|
||||||
|
</form>
|
||||||
|
`
|
||||||
} else {
|
} else {
|
||||||
content = `
|
content = `
|
||||||
<h1 class="main-title">Login</h1>
|
<h1 class="main-title">Login</h1>
|
||||||
<form method="post" class="pure-form pure-form-aligned primary-form">
|
<form method="post" class="pure-form pure-form-aligned primary-form">
|
||||||
` + vu.TernStr(len(data.OkMsg) != 0, "<p>"+data.OkMsg+" <a href=\"/\">Login</a></p>", "") + `
|
` + vu.TernStr(len(data.OkMsg) != 0, "<p>"+data.OkMsg+"</p>", "") + `
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<div class="pure-control-group">
|
<div class="pure-control-group">
|
||||||
<label for="username">Username</label>
|
<label for="username">Username</label>
|
||||||
|
@ -39,19 +43,13 @@ func Index(data IndexData) string {
|
||||||
<label for="password">Password</label>
|
<label for="password">Password</label>
|
||||||
<input type="password" placeholder="Password" name="password" id="password" />
|
<input type="password" placeholder="Password" name="password" id="password" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
` + vu.TernStr(len(data.ErrMsg) != 0, "<p>ERROR! "+data.ErrMsg+"<p>", "") + `
|
` + vu.TernStr(len(data.ErrMsg) != 0, "<p>ERROR! "+data.ErrMsg+"<p>", "") + `
|
||||||
|
|
||||||
<div class="pure-controls">
|
<div class="pure-controls">
|
||||||
<a href="/register" class="pure-button">Register</a>
|
<a href="/register" class="pure-button">Register</a>
|
||||||
<button type="submit" class="pure-button pure-button-primary">Login</button>
|
<button type="submit" class="pure-button pure-button-primary">Login</button>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<form method="post" action="/logout">
|
|
||||||
<button type="submit">Logout</button>
|
|
||||||
</form>
|
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
16
src/views/logout.go
Normal file
16
src/views/logout.go
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
package views
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gitlab.larvit.se/power-plan/auth-ui/src/views/layouts"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Logout() string {
|
||||||
|
content := `
|
||||||
|
<h1 class="main-title">Logged out</h1>
|
||||||
|
<a href="/">Login again</a>
|
||||||
|
`
|
||||||
|
return layouts.Default(layouts.DefaultData{
|
||||||
|
Content: content,
|
||||||
|
Title: "Logged out",
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user