浏览代码

enhance: 2FA is no longer required for the first 3min of login

Jacky 9 月之前
父节点
当前提交
83981349d7
共有 6 个文件被更改,包括 28 次插入15 次删除
  1. 13 7
      api/user/auth.go
  2. 2 0
      app/src/api/auth.ts
  3. 1 1
      app/src/lib/websocket/index.ts
  4. 1 1
      app/src/version.json
  5. 7 2
      app/src/views/other/Login.vue
  6. 4 4
      app/src/views/system/About.vue

+ 13 - 7
api/user/auth.go

@@ -32,10 +32,11 @@ const (
 )
 
 type LoginResponse struct {
-	Message string `json:"message"`
-	Error   string `json:"error,omitempty"`
-	Code    int    `json:"code"`
-	Token   string `json:"token,omitempty"`
+	Message         string `json:"message"`
+	Error           string `json:"error,omitempty"`
+	Code            int    `json:"code"`
+	Token           string `json:"token,omitempty"`
+	SecureSessionID string `json:"secure_session_id,omitempty"`
 }
 
 func Login(c *gin.Context) {
@@ -86,6 +87,8 @@ func Login(c *gin.Context) {
 	}
 
 	// Check if the user enables 2FA
+	var secureSessionID string
+
 	if u.EnabledOTP() {
 		if json.OTP == "" && json.RecoveryCode == "" {
 			c.JSON(http.StatusOK, LoginResponse{
@@ -104,6 +107,8 @@ func Login(c *gin.Context) {
 			user.BanIP(clientIP)
 			return
 		}
+
+		secureSessionID = user.SetSecureSessionID(u.ID)
 	}
 
 	// login success, clear banned record
@@ -119,9 +124,10 @@ func Login(c *gin.Context) {
 	}
 
 	c.JSON(http.StatusOK, LoginResponse{
-		Code:    LoginSuccess,
-		Message: "ok",
-		Token:   token,
+		Code:            LoginSuccess,
+		Message:         "ok",
+		Token:           token,
+		SecureSessionID: secureSessionID,
 	})
 }
 

+ 2 - 0
app/src/api/auth.ts

@@ -7,6 +7,8 @@ export interface AuthResponse {
   message: string
   token: string
   code: number
+  error: string
+  secure_session_id: string
 }
 
 const auth = {

+ 1 - 1
app/src/lib/websocket/index.ts

@@ -16,7 +16,7 @@ function ws(url: string, reconnect: boolean = true): ReconnectingWebSocket | Web
     url, `?token=${btoa(token.value)}`, node_id)
 
   if (reconnect)
-    return new ReconnectingWebSocket(_url)
+    return new ReconnectingWebSocket(_url, undefined, { maxRetries: 10 })
 
   return new WebSocket(_url)
 }

+ 1 - 1
app/src/version.json

@@ -1 +1 @@
-{"version":"2.0.0-beta.29","build_id":151,"total_build":355}
+{"version":"2.0.0-beta.29","build_id":152,"total_build":356}

+ 7 - 2
app/src/views/other/Login.vue

@@ -1,6 +1,7 @@
 <script setup lang="ts">
 import { LockOutlined, UserOutlined } from '@ant-design/icons-vue'
 import { Form, message } from 'ant-design-vue'
+import { useCookies } from '@vueuse/integrations/useCookies'
 import { useUserStore } from '@/pinia'
 import auth from '@/api/auth'
 import install from '@/api/install'
@@ -46,7 +47,9 @@ const rulesRef = reactive({
 })
 
 const { validate, validateInfos, clearValidate } = Form.useForm(modelRef, rulesRef)
-const { login } = useUserStore()
+const userStore = useUserStore()
+const { login } = userStore
+const { secureSessionId } = storeToRefs(userStore)
 
 const onSubmit = () => {
   validate().then(async () => {
@@ -54,11 +57,13 @@ const onSubmit = () => {
 
     await auth.login(modelRef.username, modelRef.password, passcode.value, recoveryCode.value).then(async r => {
       const next = (route.query?.next || '').toString() || '/'
-
+      const cookies = useCookies(['nginx-ui-2fa'])
       switch (r.code) {
         case 200:
           message.success($gettext('Login successful'), 1)
           login(r.token)
+          secureSessionId.value = r.secure_session_id
+          cookies.set('secure_session_id', r.secure_session_id, { maxAge: 60 * 3 })
           await router.push(next)
           break
         case 199:

+ 4 - 4
app/src/views/system/About.vue

@@ -1,9 +1,9 @@
 <script setup lang="ts">
 import GithubButton from 'vue-github-button'
 import logo from '@/assets/img/logo.png'
-import version from '@/version.json'
+import ver from '@/version.json'
 
-const this_year = new Date().getFullYear()
+const thisYear = new Date().getFullYear()
 </script>
 
 <template>
@@ -19,7 +19,7 @@ const this_year = new Date().getFullYear()
     </div>
     <h2>Nginx UI</h2>
     <p>Yet another WebUI for Nginx</p>
-    <p>Version: {{ version.version }} ({{ version.build_id || $gettext('Development Mode') }})</p>
+    <p>Version: {{ ver.version }} ({{ ver.build_id || $gettext('Development Mode') }})</p>
     <div class="star-on-github">
       <GithubButton
         href="https://github.com/0xJacky/nginx-ui"
@@ -47,7 +47,7 @@ const this_year = new Date().getFullYear()
       {{ $gettext('License') }}
     </h3>
     <p>GNU General Public License v3.0</p>
-    <p>Copyright © 2021 - {{ this_year }} Nginx UI Team</p>
+    <p>Copyright © 2021 - {{ thisYear }} Nginx UI Team</p>
   </ACard>
 </template>