@@ -3,7 +3,6 @@ package api
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -34,7 +33,9 @@ type loginRequest struct {
|
||||
// @Param body body loginRequest true "登录凭据"
|
||||
// @Success 200 {object} tokenResponse "token 与 expiresAt"
|
||||
// @Failure 401 {object} errorResponse "凭据错误"
|
||||
// @Failure 403 {object} errorResponse "密码登录已禁用"
|
||||
// @Failure 428 {object} totpRequiredResponse "需要两步验证码(totpRequired=true)"
|
||||
// @Failure 429 {object} errorResponse "登录守卫锁定(无 code);全局 IP 限流时 code=RateLimited"
|
||||
// @Router /api/v1/auth/login [post]
|
||||
func (h *authHandler) login(c *gin.Context) {
|
||||
var req loginRequest
|
||||
@@ -43,7 +44,7 @@ func (h *authHandler) login(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
start := time.Now()
|
||||
token, expires, err := h.svc.Login(c.Request.Context(), req.Username, req.Password, requestIP(c), req.TotpCode)
|
||||
token, expires, err := h.svc.Login(c.Request.Context(), req.Username, req.Password, req.TotpCode, sessionMetaOf(c))
|
||||
if errors.Is(err, service.ErrTotpRequired) {
|
||||
// 密码已通过,引导前端弹出二次验证输入;不算失败不留痕
|
||||
c.JSON(http.StatusPreconditionRequired, gin.H{"error": err.Error(), "totpRequired": true})
|
||||
@@ -80,9 +81,8 @@ func (h *authHandler) login(c *gin.Context) {
|
||||
// @Security BearerAuth
|
||||
// @Router /api/v1/auth/logout [post]
|
||||
func (h *authHandler) logout(c *gin.Context) {
|
||||
token, ok := strings.CutPrefix(c.GetHeader("Authorization"), "Bearer ")
|
||||
if ok && token != "" {
|
||||
h.svc.Logout(token)
|
||||
if token := bearerToken(c); token != "" {
|
||||
h.svc.Logout(c.Request.Context(), token)
|
||||
}
|
||||
c.Status(http.StatusNoContent)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user