feat: support basic user system
This commit is contained in:
73
internal/handler/auth.go
Normal file
73
internal/handler/auth.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"regexp"
|
||||
|
||||
"gitea.starryskymeow.cn/B309/datamarket/internal/service"
|
||||
"github.com/go-chi/jwtauth/v5"
|
||||
"github.com/go-chi/render"
|
||||
)
|
||||
|
||||
type LoginRequest struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
const usernameExpr = `^\S{3,32}$`
|
||||
const passwordExpr = `^\S{8,64}$`
|
||||
|
||||
func (req *LoginRequest) Bind(_ *http.Request) error {
|
||||
// username
|
||||
if ok, _ := regexp.MatchString(usernameExpr, req.Username); !ok {
|
||||
return fmt.Errorf("invalid username, must match %q", usernameExpr)
|
||||
}
|
||||
|
||||
// password
|
||||
if ok, _ := regexp.MatchString(passwordExpr, req.Password); !ok {
|
||||
return fmt.Errorf("invalid password, must match %q", passwordExpr)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// LoginHandler POST /api/auth/login
|
||||
func LoginHandler(auth service.AuthService) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
req := &LoginRequest{}
|
||||
if err := render.Bind(r, req); err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
renderServiceError(w, r, err)
|
||||
return
|
||||
}
|
||||
user, err := auth.VerifyUser(r.Context(), service.VerifyUserInput{
|
||||
Username: req.Username,
|
||||
Password: req.Password,
|
||||
})
|
||||
if err != nil {
|
||||
renderServiceError(w, r, err)
|
||||
return
|
||||
}
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: "jwt",
|
||||
Value: user.Token,
|
||||
Path: "/",
|
||||
HttpOnly: true,
|
||||
Secure: true,
|
||||
MaxAge: 60 * 60 * 24, // 1d
|
||||
SameSite: http.SameSiteLaxMode,
|
||||
})
|
||||
renderSuccess(w, r, http.StatusAccepted, "登录成功", user)
|
||||
}
|
||||
}
|
||||
|
||||
func MeHandler(auth service.AuthService) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
_, claims, err := jwtauth.FromContext(r.Context())
|
||||
if err != nil {
|
||||
renderServiceError(w, r, err)
|
||||
}
|
||||
renderSuccess(w, r, http.StatusOK, "logged in", claims)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user