Working login, register, logout

This commit is contained in:
Lilleman auf Larv 2022-04-22 16:58:02 +02:00
parent ec708a7723
commit 96e884f0a2
8 changed files with 74 additions and 29 deletions

View File

@ -9,7 +9,7 @@ services:
- POSTGRES_DB=auth
auth-api-db-migrate:
image: lilleman/auth-api-db-migrate:0.3.3
image: lilleman/auth-api-db-migrate:0.3.7
environment:
- DATABASE_URL=postgres://postgres:postgres@postgres:5432/auth?sslmode=disable
command: ["--wait", "up"]
@ -18,7 +18,7 @@ services:
- postgres
auth-api:
image: lilleman/auth-api:0.3.3
image: lilleman/auth-api:0.3.7
environment:
- ADMIN_API_KEY=hihi
- DATABASE_URL=postgres://postgres:postgres@postgres:5432/auth?sslmode=disable

View File

@ -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))
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
}
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{}
res, err := httpClient.Do(req)
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
}
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
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")
}
body, err := ioutil.ReadAll(res.Body)
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
}

View File

@ -19,7 +19,20 @@ type LoginUser struct {
// Index GET
func (h Handlers) Index(c *fiber.Ctx) error {
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
@ -45,8 +58,6 @@ func (h Handlers) IndexPost(c *fiber.Ctx) error {
return c.Status(500).SendString(views.Error500())
}
h.Log.Debug("API res status", "status", apiRes.StatusCode)
if apiRes.StatusCode == 200 {
err = utils.SetTokenCookies(apiRes.Body, c, h.Log)
if err != nil {
@ -54,18 +65,24 @@ func (h Handlers) IndexPost(c *fiber.Ctx) error {
return c.Status(500).SendString(views.Error500())
}
userToken := c.Cookies("userToken")
parsed, err := utils.ParseAndValidateToken(userToken, h.Api.JwtSharedSecret, h.Log)
tokens, err := utils.ParseTokenApiResBody(apiRes.Body, 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 {
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())
}
c.Locals("user", parsed)
return c.SendString(views.Index(views.IndexData{
OkMsg: "User logged in!",
Title: "Dashboard",
OkMsg: "User logged in!",
Title: "Dashboard",
UserLoggedIn: true,
}))
} else if strconv.Itoa(apiRes.StatusCode)[0:1] == "4" {
var jsonResp []api.ApiResError

View File

@ -2,6 +2,7 @@ package handlers
import (
"github.com/gofiber/fiber/v2"
"gitlab.larvit.se/power-plan/auth-ui/src/views"
)
// Logout
@ -10,6 +11,6 @@ func (h Handlers) LogoutPost(c *fiber.Ctx) error {
c.ClearCookie("renewalToken")
c.Locals("user", "")
c.Redirect("/")
return nil
c.Set(fiber.HeaderContentType, fiber.MIMETextHTML)
return c.SendString(views.Logout())
}

View File

@ -58,6 +58,8 @@ func (h Handlers) HandleCookieTokens(c *fiber.Ctx) error {
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)
if err != nil {
h.Log.Error("Could not unmarshal body from auth API", "err", err.Error())

View File

@ -41,15 +41,15 @@ func GetLog() *zap.SugaredLogger {
return log
}
type authClaims struct {
type AuthClaims struct {
jwt.StandardClaims
AccountId string `json:"accountId"`
AccountFields map[string][]string `json:"accountFields"`
AccountName string `json:"accountName"`
}
func ParseAndValidateToken(token string, jwtSecret string, log *zap.SugaredLogger) (authClaims, error) {
var claims authClaims
func ParseAndValidateToken(token string, jwtSecret string, log *zap.SugaredLogger) (AuthClaims, error) {
var claims AuthClaims
_, err := jwt.ParseWithClaims(token, &claims, func(token *jwt.Token) (interface{}, error) {
_, ok := token.Method.(*jwt.SigningMethodHMAC)
@ -65,7 +65,7 @@ func ParseAndValidateToken(token string, jwtSecret string, log *zap.SugaredLogge
} else {
log.Error("could not parse token with claims", "err", err.Error())
}
return authClaims{}, err
return AuthClaims{}, err
}
return claims, nil
@ -76,14 +76,25 @@ type AuthRes struct {
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
err := json.Unmarshal(apiResBody, &authRes)
if err != nil {
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
}
log.Debug("setting cookies", "userToken", authRes.Jwt, "len(renewalToken)", len(authRes.RenewalToken))
c.Cookie(&fiber.Cookie{
Name: "userToken",
Value: authRes.Jwt,

View File

@ -23,12 +23,16 @@ func Index(data IndexData) string {
if data.UserLoggedIn {
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 {
content = `
<h1 class="main-title">Login</h1>
<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>
<div class="pure-control-group">
<label for="username">Username</label>
@ -39,19 +43,13 @@ func Index(data IndexData) string {
<label for="password">Password</label>
<input type="password" placeholder="Password" name="password" id="password" />
</div>
` + vu.TernStr(len(data.ErrMsg) != 0, "<p>ERROR! "+data.ErrMsg+"<p>", "") + `
<div class="pure-controls">
<a href="/register" class="pure-button">Register</a>
<button type="submit" class="pure-button pure-button-primary">Login</button>
</div>
</fieldset>
</form>
<form method="post" action="/logout">
<button type="submit">Logout</button>
</form>
`
}

16
src/views/logout.go Normal file
View 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",
})
}