feat: 2FA authorization for web terminal

This commit is contained in:
Jacky 2024-07-23 20:35:32 +08:00
parent 802d05f692
commit 3a22861640
No known key found for this signature in database
GPG key ID: 215C21B10DF38B4D
15 changed files with 359 additions and 54 deletions

31
internal/cache/cache.go vendored Normal file
View file

@ -0,0 +1,31 @@
package cache
import (
"github.com/0xJacky/Nginx-UI/internal/logger"
"github.com/dgraph-io/ristretto"
"time"
)
var cache *ristretto.Cache
func Init() {
var err error
cache, err = ristretto.NewCache(&ristretto.Config{
NumCounters: 1e7, // number of keys to track frequency of (10M).
MaxCost: 1 << 30, // maximum cost of cache (1GB).
BufferItems: 64, // number of keys per Get buffer.
})
if err != nil {
logger.Fatal("initializing local cache err", err)
}
}
func Set(key interface{}, value interface{}, ttl time.Duration) {
cache.SetWithTTL(key, value, 0, ttl)
cache.Wait()
}
func Get(key interface{}) (value interface{}, ok bool) {
return cache.Get(key)
}

View file

@ -4,6 +4,7 @@ import (
"crypto/rand"
"encoding/hex"
"github.com/0xJacky/Nginx-UI/internal/analytic"
"github.com/0xJacky/Nginx-UI/internal/cache"
"github.com/0xJacky/Nginx-UI/internal/cert"
"github.com/0xJacky/Nginx-UI/internal/cluster"
"github.com/0xJacky/Nginx-UI/internal/cron"
@ -26,6 +27,7 @@ func Boot() {
InitNodeSecret,
InitCryptoSecret,
validation.Init,
cache.Init,
}
syncs := []func(){

View file

@ -4,10 +4,14 @@ import (
"bytes"
"crypto/sha1"
"encoding/hex"
"fmt"
"github.com/0xJacky/Nginx-UI/internal/cache"
"github.com/0xJacky/Nginx-UI/internal/crypto"
"github.com/0xJacky/Nginx-UI/model"
"github.com/google/uuid"
"github.com/pkg/errors"
"github.com/pquerna/otp/totp"
"time"
)
var (
@ -37,3 +41,23 @@ func VerifyOTP(user *model.Auth, otp, recoveryCode string) (err error) {
}
return
}
func secureSessionIDCacheKey(sessionId string) string {
return fmt.Sprintf("otp_secure_session:_%s", sessionId)
}
func SetSecureSessionID(userId int) (sessionId string) {
sessionId = uuid.NewString()
cache.Set(secureSessionIDCacheKey(sessionId), userId, 5*time.Minute)
return
}
func VerifySecureSessionID(sessionId string, userId int) bool {
if v, ok := cache.Get(secureSessionIDCacheKey(sessionId)); ok {
if v.(int) == userId {
return true
}
}
return false
}