mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-19 08:19:15 +08:00
fix: 登陆接口增加安全入口校验 (#2199)
This commit is contained in:
parent
278fac6d80
commit
df5a1b3e40
@ -1,6 +1,8 @@
|
|||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||||
@ -20,6 +22,7 @@ type BaseApi struct{}
|
|||||||
// @Param request body dto.Login true "request"
|
// @Param request body dto.Login true "request"
|
||||||
// @Success 200 {object} dto.UserLoginInfo
|
// @Success 200 {object} dto.UserLoginInfo
|
||||||
// @Router /auth/login [post]
|
// @Router /auth/login [post]
|
||||||
|
// @Header 200 {string} EntranceCode "安全入口"
|
||||||
func (b *BaseApi) Login(c *gin.Context) {
|
func (b *BaseApi) Login(c *gin.Context) {
|
||||||
var req dto.Login
|
var req dto.Login
|
||||||
if err := c.ShouldBindJSON(&req); err != nil {
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
@ -32,8 +35,13 @@ func (b *BaseApi) Login(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
entranceItem := c.Request.Header.Get("EntranceCode")
|
||||||
|
var entrance []byte
|
||||||
|
if len(entranceItem) != 0 {
|
||||||
|
entrance, _ = base64.StdEncoding.DecodeString(entranceItem)
|
||||||
|
}
|
||||||
|
|
||||||
user, err := authService.Login(c, req)
|
user, err := authService.Login(c, req, string(entrance))
|
||||||
go saveLoginLogs(c, err)
|
go saveLoginLogs(c, err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
@ -49,6 +57,7 @@ func (b *BaseApi) Login(c *gin.Context) {
|
|||||||
// @Param request body dto.MFALogin true "request"
|
// @Param request body dto.MFALogin true "request"
|
||||||
// @Success 200 {object} dto.UserLoginInfo
|
// @Success 200 {object} dto.UserLoginInfo
|
||||||
// @Router /auth/mfalogin [post]
|
// @Router /auth/mfalogin [post]
|
||||||
|
// @Header 200 {string} EntranceCode "安全入口"
|
||||||
func (b *BaseApi) MFALogin(c *gin.Context) {
|
func (b *BaseApi) MFALogin(c *gin.Context) {
|
||||||
var req dto.MFALogin
|
var req dto.MFALogin
|
||||||
if err := c.ShouldBindJSON(&req); err != nil {
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
@ -59,8 +68,13 @@ func (b *BaseApi) MFALogin(c *gin.Context) {
|
|||||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
entranceItem := c.Request.Header.Get("EntranceCode")
|
||||||
|
var entrance []byte
|
||||||
|
if len(entranceItem) != 0 {
|
||||||
|
entrance, _ = base64.StdEncoding.DecodeString(entranceItem)
|
||||||
|
}
|
||||||
|
|
||||||
user, err := authService.MFALogin(c, req)
|
user, err := authService.MFALogin(c, req, string(entrance))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
return
|
return
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/buserr"
|
||||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||||
"github.com/1Panel-dev/1Panel/backend/global"
|
"github.com/1Panel-dev/1Panel/backend/global"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/encrypt"
|
"github.com/1Panel-dev/1Panel/backend/utils/encrypt"
|
||||||
@ -19,16 +20,16 @@ type AuthService struct{}
|
|||||||
type IAuthService interface {
|
type IAuthService interface {
|
||||||
CheckIsSafety(code string) (string, error)
|
CheckIsSafety(code string) (string, error)
|
||||||
VerifyCode(code string) (bool, error)
|
VerifyCode(code string) (bool, error)
|
||||||
Login(c *gin.Context, info dto.Login) (*dto.UserLoginInfo, error)
|
Login(c *gin.Context, info dto.Login, entrance string) (*dto.UserLoginInfo, error)
|
||||||
LogOut(c *gin.Context) error
|
LogOut(c *gin.Context) error
|
||||||
MFALogin(c *gin.Context, info dto.MFALogin) (*dto.UserLoginInfo, error)
|
MFALogin(c *gin.Context, info dto.MFALogin, entrance string) (*dto.UserLoginInfo, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIAuthService() IAuthService {
|
func NewIAuthService() IAuthService {
|
||||||
return &AuthService{}
|
return &AuthService{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *AuthService) Login(c *gin.Context, info dto.Login) (*dto.UserLoginInfo, error) {
|
func (u *AuthService) Login(c *gin.Context, info dto.Login, entrance string) (*dto.UserLoginInfo, error) {
|
||||||
nameSetting, err := settingRepo.Get(settingRepo.WithByKey("UserName"))
|
nameSetting, err := settingRepo.Get(settingRepo.WithByKey("UserName"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.WithMessage(constant.ErrRecordNotFound, err.Error())
|
return nil, errors.WithMessage(constant.ErrRecordNotFound, err.Error())
|
||||||
@ -44,6 +45,13 @@ func (u *AuthService) Login(c *gin.Context, info dto.Login) (*dto.UserLoginInfo,
|
|||||||
if info.Password != pass || nameSetting.Value != info.Name {
|
if info.Password != pass || nameSetting.Value != info.Name {
|
||||||
return nil, constant.ErrAuth
|
return nil, constant.ErrAuth
|
||||||
}
|
}
|
||||||
|
entranceSetting, err := settingRepo.Get(settingRepo.WithByKey("SecurityEntrance"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(entranceSetting.Value) != 0 && entranceSetting.Value != entrance {
|
||||||
|
return nil, buserr.New(constant.ErrEntrance)
|
||||||
|
}
|
||||||
mfa, err := settingRepo.Get(settingRepo.WithByKey("MFAStatus"))
|
mfa, err := settingRepo.Get(settingRepo.WithByKey("MFAStatus"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -57,7 +65,7 @@ func (u *AuthService) Login(c *gin.Context, info dto.Login) (*dto.UserLoginInfo,
|
|||||||
return u.generateSession(c, info.Name, info.AuthMethod)
|
return u.generateSession(c, info.Name, info.AuthMethod)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *AuthService) MFALogin(c *gin.Context, info dto.MFALogin) (*dto.UserLoginInfo, error) {
|
func (u *AuthService) MFALogin(c *gin.Context, info dto.MFALogin, entrance string) (*dto.UserLoginInfo, error) {
|
||||||
nameSetting, err := settingRepo.Get(settingRepo.WithByKey("UserName"))
|
nameSetting, err := settingRepo.Get(settingRepo.WithByKey("UserName"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.WithMessage(constant.ErrRecordNotFound, err.Error())
|
return nil, errors.WithMessage(constant.ErrRecordNotFound, err.Error())
|
||||||
@ -73,7 +81,13 @@ func (u *AuthService) MFALogin(c *gin.Context, info dto.MFALogin) (*dto.UserLogi
|
|||||||
if info.Password != pass || nameSetting.Value != info.Name {
|
if info.Password != pass || nameSetting.Value != info.Name {
|
||||||
return nil, constant.ErrAuth
|
return nil, constant.ErrAuth
|
||||||
}
|
}
|
||||||
|
entranceSetting, err := settingRepo.Get(settingRepo.WithByKey("SecurityEntrance"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(entranceSetting.Value) != 0 && entranceSetting.Value != entrance {
|
||||||
|
return nil, buserr.New(constant.ErrEntrance)
|
||||||
|
}
|
||||||
mfaSecret, err := settingRepo.Get(settingRepo.WithByKey("MFASecret"))
|
mfaSecret, err := settingRepo.Get(settingRepo.WithByKey("MFASecret"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -124,4 +124,5 @@ var (
|
|||||||
var (
|
var (
|
||||||
ErrBackupInUsed = "ErrBackupInUsed"
|
ErrBackupInUsed = "ErrBackupInUsed"
|
||||||
ErrOSSConn = "ErrOSSConn"
|
ErrOSSConn = "ErrOSSConn"
|
||||||
|
ErrEntrance = "ErrEntrance"
|
||||||
)
|
)
|
||||||
|
@ -104,6 +104,7 @@ ErrDelWithWebsite: "The operating environment has been associated with a website
|
|||||||
#setting
|
#setting
|
||||||
ErrBackupInUsed: "The backup account is already being used in a cronjob and cannot be deleted."
|
ErrBackupInUsed: "The backup account is already being used in a cronjob and cannot be deleted."
|
||||||
ErrOSSConn: "Unable to successfully request the latest version. Please check if the server can connect to the external network environment."
|
ErrOSSConn: "Unable to successfully request the latest version. Please check if the server can connect to the external network environment."
|
||||||
|
ErrEntrance: "Security entrance information error. Please check and try again!"
|
||||||
|
|
||||||
#tool
|
#tool
|
||||||
ErrConfigNotFound: "Configuration file does not exist"
|
ErrConfigNotFound: "Configuration file does not exist"
|
||||||
|
@ -104,6 +104,7 @@ ErrDelWithWebsite: "運行環境已經關聯網站,無法刪除"
|
|||||||
#setting
|
#setting
|
||||||
ErrBackupInUsed: "該備份帳號已在計劃任務中使用,無法刪除"
|
ErrBackupInUsed: "該備份帳號已在計劃任務中使用,無法刪除"
|
||||||
ErrOSSConn: "無法成功請求最新版本,請檢查伺服器是否能夠連接到外部網絡環境。"
|
ErrOSSConn: "無法成功請求最新版本,請檢查伺服器是否能夠連接到外部網絡環境。"
|
||||||
|
ErrEntrance: "安全入口信息錯誤,請檢查後重試!"
|
||||||
|
|
||||||
#tool
|
#tool
|
||||||
ErrConfigNotFound: "配置文件不存在"
|
ErrConfigNotFound: "配置文件不存在"
|
||||||
|
@ -104,6 +104,7 @@ ErrDelWithWebsite: "运行环境已经关联网站,无法删除"
|
|||||||
#setting
|
#setting
|
||||||
ErrBackupInUsed: "该备份账号已在计划任务中使用,无法删除"
|
ErrBackupInUsed: "该备份账号已在计划任务中使用,无法删除"
|
||||||
ErrOSSConn: "无法成功请求最新版本,请检查服务器是否能够连接到外部网络环境。"
|
ErrOSSConn: "无法成功请求最新版本,请检查服务器是否能够连接到外部网络环境。"
|
||||||
|
ErrEntrance: "安全入口信息错误,请检查后重试!"
|
||||||
|
|
||||||
#tool
|
#tool
|
||||||
ErrConfigNotFound: "配置文件不存在"
|
ErrConfigNotFound: "配置文件不存在"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Package docs GENERATED BY SWAG; DO NOT EDIT
|
// Code generated by swaggo/swag. DO NOT EDIT.
|
||||||
// This file was generated by swaggo/swag
|
|
||||||
package docs
|
package docs
|
||||||
|
|
||||||
import "github.com/swaggo/swag"
|
import "github.com/swaggo/swag"
|
||||||
@ -956,6 +956,12 @@ const docTemplate = `{
|
|||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/dto.UserLoginInfo"
|
"$ref": "#/definitions/dto.UserLoginInfo"
|
||||||
|
},
|
||||||
|
"headers": {
|
||||||
|
"EntranceCode": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "安全入口"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1006,6 +1012,12 @@ const docTemplate = `{
|
|||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/dto.UserLoginInfo"
|
"$ref": "#/definitions/dto.UserLoginInfo"
|
||||||
|
},
|
||||||
|
"headers": {
|
||||||
|
"EntranceCode": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "安全入口"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -14925,6 +14937,9 @@ const docTemplate = `{
|
|||||||
"extension": {
|
"extension": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"gid": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"group": {
|
"group": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -14970,6 +14985,9 @@ const docTemplate = `{
|
|||||||
"type": {
|
"type": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"uid": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"updateTime": {
|
"updateTime": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -17313,6 +17331,9 @@ const docTemplate = `{
|
|||||||
"extension": {
|
"extension": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"gid": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"group": {
|
"group": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -17358,6 +17379,9 @@ const docTemplate = `{
|
|||||||
"type": {
|
"type": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"uid": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"updateTime": {
|
"updateTime": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
@ -949,6 +949,12 @@
|
|||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/dto.UserLoginInfo"
|
"$ref": "#/definitions/dto.UserLoginInfo"
|
||||||
|
},
|
||||||
|
"headers": {
|
||||||
|
"EntranceCode": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "安全入口"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -999,6 +1005,12 @@
|
|||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/dto.UserLoginInfo"
|
"$ref": "#/definitions/dto.UserLoginInfo"
|
||||||
|
},
|
||||||
|
"headers": {
|
||||||
|
"EntranceCode": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "安全入口"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -14918,6 +14930,9 @@
|
|||||||
"extension": {
|
"extension": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"gid": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"group": {
|
"group": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -14963,6 +14978,9 @@
|
|||||||
"type": {
|
"type": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"uid": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"updateTime": {
|
"updateTime": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -17306,6 +17324,9 @@
|
|||||||
"extension": {
|
"extension": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"gid": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"group": {
|
"group": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -17351,6 +17372,9 @@
|
|||||||
"type": {
|
"type": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"uid": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"updateTime": {
|
"updateTime": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
@ -2177,6 +2177,8 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
extension:
|
extension:
|
||||||
type: string
|
type: string
|
||||||
|
gid:
|
||||||
|
type: string
|
||||||
group:
|
group:
|
||||||
type: string
|
type: string
|
||||||
isDir:
|
isDir:
|
||||||
@ -2207,6 +2209,8 @@ definitions:
|
|||||||
type: integer
|
type: integer
|
||||||
type:
|
type:
|
||||||
type: string
|
type: string
|
||||||
|
uid:
|
||||||
|
type: string
|
||||||
updateTime:
|
updateTime:
|
||||||
type: string
|
type: string
|
||||||
user:
|
user:
|
||||||
@ -3778,6 +3782,8 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
extension:
|
extension:
|
||||||
type: string
|
type: string
|
||||||
|
gid:
|
||||||
|
type: string
|
||||||
group:
|
group:
|
||||||
type: string
|
type: string
|
||||||
isDir:
|
isDir:
|
||||||
@ -3808,6 +3814,8 @@ definitions:
|
|||||||
type: integer
|
type: integer
|
||||||
type:
|
type:
|
||||||
type: string
|
type: string
|
||||||
|
uid:
|
||||||
|
type: string
|
||||||
updateTime:
|
updateTime:
|
||||||
type: string
|
type: string
|
||||||
user:
|
user:
|
||||||
@ -4620,6 +4628,10 @@ paths:
|
|||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: OK
|
description: OK
|
||||||
|
headers:
|
||||||
|
EntranceCode:
|
||||||
|
description: 安全入口
|
||||||
|
type: string
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/dto.UserLoginInfo'
|
$ref: '#/definitions/dto.UserLoginInfo'
|
||||||
summary: User login
|
summary: User login
|
||||||
@ -4651,6 +4663,10 @@ paths:
|
|||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: OK
|
description: OK
|
||||||
|
headers:
|
||||||
|
EntranceCode:
|
||||||
|
description: 安全入口
|
||||||
|
type: string
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/dto.UserLoginInfo'
|
$ref: '#/definitions/dto.UserLoginInfo'
|
||||||
summary: User login with mfa
|
summary: User login with mfa
|
||||||
|
@ -5,6 +5,7 @@ import { checkStatus } from './helper/check-status';
|
|||||||
import router from '@/routers';
|
import router from '@/routers';
|
||||||
import { GlobalStore } from '@/store';
|
import { GlobalStore } from '@/store';
|
||||||
import { MsgError } from '@/utils/message';
|
import { MsgError } from '@/utils/message';
|
||||||
|
import { Base64 } from 'js-base64';
|
||||||
|
|
||||||
const globalStore = GlobalStore();
|
const globalStore = GlobalStore();
|
||||||
|
|
||||||
@ -25,6 +26,10 @@ class RequestHttp {
|
|||||||
'Accept-Language': language,
|
'Accept-Language': language,
|
||||||
...config.headers,
|
...config.headers,
|
||||||
};
|
};
|
||||||
|
if (config.url === '/auth/login' || config.url === '/auth/mfalogin') {
|
||||||
|
let entrace = Base64.encode(globalStore.entrance);
|
||||||
|
config.headers.EntranceCode = entrace;
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
...config,
|
...config,
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user