add logout method
This commit is contained in:
82
api/auth/logout.go
Normal file
82
api/auth/logout.go
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
package api_auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"git.oblat.lv/alex/triggerssmith/internal/auth"
|
||||||
|
"git.oblat.lv/alex/triggerssmith/internal/server"
|
||||||
|
"github.com/golang-jwt/jwt/v5"
|
||||||
|
)
|
||||||
|
|
||||||
|
// @Summary Logout
|
||||||
|
// @Description Requires valid refresh token
|
||||||
|
// @Tags auth
|
||||||
|
// @Success 204
|
||||||
|
// @Failure 401 {object} server.ProblemDetails
|
||||||
|
// @Failure 500 {object} server.ProblemDetails
|
||||||
|
// @Router /api/auth/logout [post]
|
||||||
|
func (h *authHandler) handleLogout(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// claims, err := h.a.AuthenticateRequest(r)
|
||||||
|
// if err != nil {
|
||||||
|
// slog.Error("failed to AuthenticateRequest", "error", err.Error())
|
||||||
|
// switch err {
|
||||||
|
// case auth.ErrInvalidToken:
|
||||||
|
// server.WriteProblem(w, http.StatusUnauthorized, "/errors/auth/invalid-token", "Invalid token", "Invalid token: taking cookies anyways", r)
|
||||||
|
// case auth.ErrTokenIsMissing:
|
||||||
|
// server.WriteProblem(w, http.StatusUnauthorized, "/errors/auth/invalid-token", "Invalid token", "Token is missing: taking cookies anyway", r)
|
||||||
|
// default:
|
||||||
|
// server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error: taking cookies anyway", r)
|
||||||
|
// }
|
||||||
|
// http.SetCookie(w, &http.Cookie{
|
||||||
|
// Name: "refresh_token",
|
||||||
|
// Value: "",
|
||||||
|
// MaxAge: -1,
|
||||||
|
// Path: "/api/auth/",
|
||||||
|
// HttpOnly: true,
|
||||||
|
// SameSite: http.SameSiteLaxMode,
|
||||||
|
// })
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// rjti := claims.(jwt.MapClaims)["rjti"].(string)
|
||||||
|
refreshCookie, err := r.Cookie("refresh_token")
|
||||||
|
if err != nil && errors.Is(err, http.ErrNoCookie) {
|
||||||
|
server.WriteProblem(w, http.StatusUnauthorized, "/errors/auth/refresh-token-not-found", "Refresh token is missing", "Refresh token is missing", r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
refreshStr := refreshCookie.Value
|
||||||
|
if refreshStr == "" {
|
||||||
|
server.WriteProblem(w, http.StatusUnauthorized, "/errors/auth/refresh-token-not-found", "Refresh token is missing", "Refresh token is missing", r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
claims, err := h.a.ValidateRefreshToken(refreshStr)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("failed to ValidateRefreshToken", "error", err.Error())
|
||||||
|
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error while validating refresh token: maybe invalid", r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rjti := claims.(jwt.MapClaims)["jti"].(string)
|
||||||
|
err = h.a.Logout(rjti)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("failed to Logout", "error", err.Error())
|
||||||
|
switch err {
|
||||||
|
case auth.ErrInvalidToken:
|
||||||
|
server.WriteProblem(w, http.StatusUnauthorized, "/errors/auth/already-revoked", "Token already revoked", fmt.Sprintf("Token with rjti '%s' is already revoked", rjti), r)
|
||||||
|
default:
|
||||||
|
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error: taking cookies anyway", r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
http.SetCookie(w, &http.Cookie{
|
||||||
|
Name: "refresh_token",
|
||||||
|
Value: "",
|
||||||
|
MaxAge: -1,
|
||||||
|
Path: "/api/auth/",
|
||||||
|
HttpOnly: true,
|
||||||
|
SameSite: http.SameSiteLaxMode,
|
||||||
|
})
|
||||||
|
if err == nil {
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user