mirror of
https://gitee.com/samwaf/SamWaf.git
synced 2025-12-06 06:58:54 +08:00
feat:add mobile login
This commit is contained in:
@@ -101,13 +101,19 @@ func (w *WafLoginApi) LoginApi(c *gin.Context) {
|
||||
// 密码正确,清除错误计数
|
||||
global.GCACHE_WAFCACHE.Remove(cacheKey)
|
||||
|
||||
//如果存在旧的状态删除 相同帐号 只允许一个
|
||||
allTokenInfo := wafTokenInfoService.GetAllTokenInfoByLoginAccount(req.LoginAccount)
|
||||
// 获取登录类型
|
||||
loginType := c.GetHeader("X-Login-Type")
|
||||
if loginType == "" {
|
||||
loginType = "web" // 默认为web类型
|
||||
}
|
||||
|
||||
//如果存在旧的状态删除 相同帐号和登录类型 只允许一个
|
||||
allTokenInfo := wafTokenInfoService.GetAllTokenInfoByLoginAccountAndType(req.LoginAccount, loginType)
|
||||
if allTokenInfo != nil {
|
||||
for i := 0; i < len(allTokenInfo); i++ {
|
||||
oldTokenInfo := allTokenInfo[i]
|
||||
if oldTokenInfo.Id != "" {
|
||||
wafTokenInfoService.DelApiByAccount(oldTokenInfo.LoginAccount)
|
||||
wafTokenInfoService.DelApiByAccountAndType(oldTokenInfo.LoginAccount, oldTokenInfo.LoginType)
|
||||
global.GCACHE_WAFCACHE.Remove(enums.CACHE_TOKEN + oldTokenInfo.AccessToken)
|
||||
}
|
||||
}
|
||||
@@ -121,7 +127,7 @@ func (w *WafLoginApi) LoginApi(c *gin.Context) {
|
||||
|
||||
//记录状态
|
||||
accessToken := utils.Md5String(uuid.GenUUID())
|
||||
tokenInfo := wafTokenInfoService.AddApiWithFingerprint(bean.LoginAccount, accessToken, c.ClientIP(), deviceFingerprint)
|
||||
tokenInfo := wafTokenInfoService.AddApiWithFingerprintAndType(bean.LoginAccount, accessToken, c.ClientIP(), deviceFingerprint, loginType)
|
||||
|
||||
//令牌记录到cache里
|
||||
global.GCACHE_WAFCACHE.SetWithTTl(enums.CACHE_TOKEN+accessToken, *tokenInfo, time.Duration(global.GCONFIG_RECORD_TOKEN_EXPIRE_MINTUTES)*time.Minute)
|
||||
@@ -165,10 +171,20 @@ func (w *WafLoginApi) LoginOutApi(c *gin.Context) {
|
||||
var req request.WafLoginOutReq
|
||||
err := c.ShouldBind(&req)
|
||||
if err == nil {
|
||||
tokenStr := c.GetHeader("X-Token")
|
||||
// 根据登录类型获取不同的token头部
|
||||
loginType := c.GetHeader("X-Login-Type")
|
||||
var tokenStr string
|
||||
|
||||
if loginType == "mobile" {
|
||||
tokenStr = c.GetHeader("X-Mobile-Token")
|
||||
} else {
|
||||
tokenStr = c.GetHeader("X-Token")
|
||||
}
|
||||
|
||||
bean := wafTokenInfoService.GetInfoByAccessToken(tokenStr)
|
||||
if bean.Id != "" {
|
||||
wafTokenInfoService.DelApi(bean.LoginAccount, bean.AccessToken)
|
||||
global.GCACHE_WAFCACHE.Remove(enums.CACHE_TOKEN + bean.AccessToken)
|
||||
response.OkWithDetailed("json", "注销成功"+tokenStr, c)
|
||||
return
|
||||
} else {
|
||||
|
||||
@@ -25,12 +25,19 @@ func Auth() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
// 获取请求头中 token,实际是一个完整被签名过的 token;a complete, signed token
|
||||
tokenStr := ""
|
||||
loginType := c.GetHeader("X-Login-Type")
|
||||
|
||||
if c.Request.RequestURI == "/samwaf/ws" {
|
||||
tokenStr = c.GetHeader("Sec-WebSocket-Protocol")
|
||||
} else if strings.HasPrefix(c.Request.RequestURI, "/samwaf/waflog/attack/download") {
|
||||
tokenStr = c.Query("X-Token")
|
||||
} else {
|
||||
tokenStr = c.GetHeader("X-Token")
|
||||
// 根据登录类型获取不同的token头部
|
||||
if loginType == "mobile" {
|
||||
tokenStr = c.GetHeader("X-Mobile-Token")
|
||||
} else {
|
||||
tokenStr = c.GetHeader("X-Token")
|
||||
}
|
||||
}
|
||||
if tokenStr == "" {
|
||||
zlog.Debug("无token")
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"SamWaf/common/zlog"
|
||||
"SamWaf/global"
|
||||
"SamWaf/wafsec"
|
||||
"bytes"
|
||||
@@ -32,6 +33,14 @@ func SecApi() gin.HandlerFunc {
|
||||
if err == nil {
|
||||
c.Request.Body = io.NopCloser(bytes.NewBuffer(decryptBytes))
|
||||
}
|
||||
} else if c.Request.Header.Get("X-Login-Type") == "mobile" && c.Request.Header.Get("Content-Type") == "application/json" {
|
||||
decryptBytes, err := wafsec.AesDecrypt(string(bodyBytes), global.GWAF_COMMUNICATION_KEY)
|
||||
if err == nil {
|
||||
c.Request.Body = io.NopCloser(bytes.NewBuffer(decryptBytes))
|
||||
} else {
|
||||
zlog.Debug("Decrypt error", err.Error())
|
||||
}
|
||||
|
||||
}
|
||||
c.Next()
|
||||
}
|
||||
|
||||
@@ -25,4 +25,5 @@ type TokenInfo struct {
|
||||
LoginIp string `json:"login_ip"` //登录IP
|
||||
AccessToken string `json:"access_token" crypto:"aes"` //访问码
|
||||
DeviceFingerprint string `json:"device_fingerprint"` //设备指纹
|
||||
LoginType string `json:"login_type"` //登录类型 web/mobile
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ func (receiver *WafTokenInfoService) AddApi(loginAccount string, AccessToken str
|
||||
LoginAccount: loginAccount,
|
||||
AccessToken: AccessToken,
|
||||
LoginIp: LoginIp,
|
||||
LoginType: "web", // 默认为web类型
|
||||
}
|
||||
global.GWAF_LOCAL_DB.Create(bean)
|
||||
mod := receiver.GetInfoByLoginAccount(loginAccount)
|
||||
@@ -49,12 +50,35 @@ func (receiver *WafTokenInfoService) AddApiWithFingerprint(loginAccount string,
|
||||
AccessToken: AccessToken,
|
||||
LoginIp: LoginIp,
|
||||
DeviceFingerprint: deviceFingerprint,
|
||||
LoginType: "web", // 默认为web类型
|
||||
}
|
||||
global.GWAF_LOCAL_DB.Create(bean)
|
||||
mod := receiver.GetInfoByLoginAccount(loginAccount)
|
||||
return &mod
|
||||
}
|
||||
|
||||
// AddApiWithFingerprintAndType 添加带指纹和登录类型的token信息
|
||||
func (receiver *WafTokenInfoService) AddApiWithFingerprintAndType(loginAccount string, AccessToken string, LoginIp string, deviceFingerprint string, loginType string) *model.TokenInfo {
|
||||
|
||||
var bean = &model.TokenInfo{
|
||||
BaseOrm: baseorm.BaseOrm{
|
||||
Id: uuid.GenUUID(),
|
||||
USER_CODE: global.GWAF_USER_CODE,
|
||||
Tenant_ID: global.GWAF_TENANT_ID,
|
||||
CREATE_TIME: customtype.JsonTime(time.Now()),
|
||||
UPDATE_TIME: customtype.JsonTime(time.Now()),
|
||||
},
|
||||
LoginAccount: loginAccount,
|
||||
AccessToken: AccessToken,
|
||||
LoginIp: LoginIp,
|
||||
DeviceFingerprint: deviceFingerprint,
|
||||
LoginType: loginType,
|
||||
}
|
||||
global.GWAF_LOCAL_DB.Create(bean)
|
||||
mod := receiver.GetInfoByLoginAccountAndType(loginAccount, loginType)
|
||||
return &mod
|
||||
}
|
||||
|
||||
func (receiver *WafTokenInfoService) CheckIsExistByLoginAccountApi(loginAccount string) error {
|
||||
return global.GWAF_LOCAL_DB.First(&model.TokenInfo{}, "login_account = ? ", loginAccount).Error
|
||||
}
|
||||
@@ -90,6 +114,20 @@ func (receiver *WafTokenInfoService) GetAllTokenInfoByLoginAccount(loginAccount
|
||||
return bean
|
||||
}
|
||||
|
||||
// GetInfoByLoginAccountAndType 通过登录account和类型获取账号信息
|
||||
func (receiver *WafTokenInfoService) GetInfoByLoginAccountAndType(loginAccount string, loginType string) model.TokenInfo {
|
||||
var bean model.TokenInfo
|
||||
global.GWAF_LOCAL_DB.Where("login_account=? AND login_type=? ", loginAccount, loginType).Limit(1).Find(&bean)
|
||||
return bean
|
||||
}
|
||||
|
||||
// GetAllTokenInfoByLoginAccountAndType 通过登录account和类型获取所有账号信息
|
||||
func (receiver *WafTokenInfoService) GetAllTokenInfoByLoginAccountAndType(loginAccount string, loginType string) []model.TokenInfo {
|
||||
var bean []model.TokenInfo
|
||||
global.GWAF_LOCAL_DB.Where("login_account=? AND login_type=? ", loginAccount, loginType).Find(&bean)
|
||||
return bean
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
获取一个可用的token TODO 将来应该是一个
|
||||
@@ -138,6 +176,20 @@ func (receiver *WafTokenInfoService) DelApiByAccount(loginAccount string) error
|
||||
return err
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
通过账号和登录类型删除关联状态
|
||||
*/
|
||||
func (receiver *WafTokenInfoService) DelApiByAccountAndType(loginAccount string, loginType string) error {
|
||||
var bean model.TokenInfo
|
||||
err := global.GWAF_LOCAL_DB.Where("login_account = ? AND login_type = ?", loginAccount, loginType).First(&bean).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = global.GWAF_LOCAL_DB.Where("login_account = ? AND login_type = ?", loginAccount, loginType).Delete(model.TokenInfo{}).Error
|
||||
return err
|
||||
}
|
||||
|
||||
/*
|
||||
* 检测所有的token是否过期,没有过期就重新加载到cache
|
||||
*/
|
||||
|
||||
@@ -117,7 +117,7 @@ func (web *WafWebManager) cors() gin.HandlerFunc {
|
||||
// 将该域添加到allow-origin中
|
||||
c.Header("Access-Control-Allow-Origin", origin) //
|
||||
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
|
||||
c.Header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization,X-Token,Remote-Waf-User-Id,OPEN-X-Token")
|
||||
c.Header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization,X-Token,Remote-Waf-User-Id,OPEN-X-Token,X-Login-Type,X-Mobile-Token")
|
||||
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Cache-Control, Content-Language, Content-Type")
|
||||
//允许客户端传递校验信息比如 cookie
|
||||
c.Header("Access-Control-Allow-Credentials", "true")
|
||||
|
||||
Reference in New Issue
Block a user