mirror of
https://github.com/simon-ding/polaris.git
synced 2026-06-08 19:17:53 +08:00
login feature
This commit is contained in:
141
server/auth.go
Normal file
141
server/auth.go
Normal file
@@ -0,0 +1,141 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"polaris/db"
|
||||
"polaris/log"
|
||||
"polaris/pkg/utils"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func (s *Server) isAuthEnabled() bool {
|
||||
authEnabled := s.db.GetSetting(db.SettingAuthEnabled)
|
||||
return authEnabled == "true"
|
||||
}
|
||||
|
||||
func (s *Server) authModdleware(c *gin.Context) {
|
||||
if !s.isAuthEnabled() {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
|
||||
auth := c.GetHeader("Authorization")
|
||||
if auth == "" {
|
||||
c.AbortWithStatus(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
auth = strings.TrimPrefix(auth, "Bearer ")
|
||||
log.Infof("current token: %v", auth)
|
||||
token, err := jwt.ParseWithClaims(auth, &jwt.RegisteredClaims{}, func(t *jwt.Token) (interface{}, error) {
|
||||
return []byte(secretKey), nil
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("parse token error: %v", err)
|
||||
c.AbortWithStatus(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
if !token.Valid {
|
||||
log.Errorf("token is not valid: %v", auth)
|
||||
c.AbortWithStatus(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
claim := token.Claims.(*jwt.RegisteredClaims)
|
||||
|
||||
if time.Until(claim.ExpiresAt.Time) <= 0 {
|
||||
log.Infof("token is no longer valid: %s", auth)
|
||||
c.AbortWithStatus(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
c.Next()
|
||||
|
||||
}
|
||||
|
||||
type LoginIn struct {
|
||||
User string `json:"user"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
const secretKey = "r1OF7nhpNjnYiGKtTLuKEVq7YznzT"
|
||||
|
||||
func (s *Server) Login(c *gin.Context) (interface{}, error) {
|
||||
var in LoginIn
|
||||
|
||||
if err := c.ShouldBindJSON(&in); err != nil {
|
||||
return nil, errors.Wrap(err, "bind json")
|
||||
}
|
||||
|
||||
if !s.isAuthEnabled() {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
user := s.db.GetSetting(db.SettingUsername)
|
||||
if user != in.User {
|
||||
return nil, errors.New("login fail")
|
||||
}
|
||||
password := s.db.GetSetting(db.SettingPassword)
|
||||
if !utils.VerifyPassword(in.Password, password) {
|
||||
return nil, errors.New("login fail")
|
||||
}
|
||||
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.RegisteredClaims{
|
||||
Issuer: "system",
|
||||
Subject: in.User,
|
||||
ExpiresAt: jwt.NewNumericDate(time.Now().Add(7 * 24 * time.Hour)),
|
||||
IssuedAt: jwt.NewNumericDate(time.Now()),
|
||||
NotBefore: jwt.NewNumericDate(time.Now()),
|
||||
})
|
||||
sig, err := token.SignedString([]byte(secretKey))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "sign")
|
||||
}
|
||||
return gin.H{
|
||||
"token": sig,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type EnableAuthIn struct {
|
||||
Enable bool `json:"enable"`
|
||||
User string `json:"user"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
func (s *Server) EnableAuth(c *gin.Context) (interface{}, error) {
|
||||
var in EnableAuthIn
|
||||
if err := c.ShouldBindJSON(&in); err != nil {
|
||||
return nil, errors.Wrap(err, "bind json")
|
||||
}
|
||||
|
||||
if in.Enable && (in.User == "" || in.Password == "") {
|
||||
return nil, errors.New("user password should not empty")
|
||||
}
|
||||
if !in.Enable {
|
||||
log.Infof("disable auth")
|
||||
s.db.SetSetting(db.SettingAuthEnabled, "false")
|
||||
} else {
|
||||
log.Info("enable auth")
|
||||
s.db.SetSetting(db.SettingAuthEnabled, "true")
|
||||
s.db.SetSetting(db.SettingUsername, in.User)
|
||||
|
||||
hash, err := utils.HashPassword(in.Password)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "hash password")
|
||||
}
|
||||
s.db.SetSetting(db.SettingPassword, hash)
|
||||
}
|
||||
return "success", nil
|
||||
}
|
||||
|
||||
func (s *Server) GetAuthSetting(c *gin.Context) (interface{}, error) {
|
||||
enabled := s.db.GetSetting(db.SettingAuthEnabled)
|
||||
user := s.db.GetSetting(db.SettingUsername)
|
||||
|
||||
return EnableAuthIn{
|
||||
Enable: enabled == "true",
|
||||
User: user,
|
||||
}, nil
|
||||
}
|
||||
@@ -38,12 +38,17 @@ func (s *Server) Serve() error {
|
||||
//st, _ := fs.Sub(ui.Web, "build/web")
|
||||
s.r.Use(static.Serve("/", static.EmbedFolder(ui.Web, "build/web")))
|
||||
|
||||
s.r.POST("/api/login", HttpHandler(s.Login))
|
||||
|
||||
api := s.r.Group("/api/v1")
|
||||
api.Use(s.authModdleware)
|
||||
|
||||
setting := api.Group("/setting")
|
||||
{
|
||||
setting.POST("/do", HttpHandler(s.SetSetting))
|
||||
setting.GET("/do", HttpHandler(s.GetSetting))
|
||||
setting.POST("/auth", HttpHandler(s.EnableAuth))
|
||||
setting.GET("/auth", HttpHandler(s.GetAuthSetting))
|
||||
}
|
||||
|
||||
tv := api.Group("/tv")
|
||||
|
||||
Reference in New Issue
Block a user