首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

App 串接 Java 後台:登入與權限驗證完整實作

     編輯:Java 相關知識

App 後台登入與權限驗證架構設計

在 App 專案開發中,使用者登入與權限驗證是核心基礎功能。本文分享如何在既有 Spring 專案中,透過 Token 機制與 Spring AOP 實現輕量級的權限控管,且不需大幅修改既有程式碼。

核心需求分析

  • App 端以帳號密碼換取 Token
  • 後續 API 請求攜帶 Token 進行身分驗證
  • 既有 URL 無統一規範,不適合用 Filter/Interceptor
  • 新增功能需輕鬆套用權限驗證

架構設計:Token + 自訂註解 + Spring AOP

1. 啟用 Spring AOP

在 Spring 設定檔中啟用 AspectJ 自動代理:

<aop:aspectj-autoproxy />

需引入 spring-aop 相關 JAR 套件,並在設定檔宣告 AOP 命名空間。

2. 定義自訂權限註解

import java.lang.annotation.*;

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface UserAccess {
}

此註解可標註在類別或方法上,作為 AOP 切入點依據。

3. Token 生成與管理服務

import org.springframework.stereotype.Service;
import java.util.*;

@Service
public class LoginService {
    // 儲存「使用者名稱:Token」對應
    public static Map<String, String> tokenMap = new HashMap<>();
    // 儲存「Token:User 物件」對應
    public static Map<String, User> loginUserMap = new HashMap<>();

    public String login(String name, String password) {
        System.out.println(name + "-----登入嘗試");

        String oldToken = tokenMap.get(name);
        User user;

        if (oldToken == null) {
            user = new User();
            user.setName(name);
            user.setPassword(password);
            System.out.println("新使用者登入");
        } else {
            user = loginUserMap.get(oldToken);
            loginUserMap.remove(oldToken);
            System.out.println("更新使用者登入 Token");
        }

        // Token 組成:username + password + 登入時間 → MD5 加密
        String token = MD5Util.MD5(name + password + System.currentTimeMillis());
        
        loginUserMap.put(token, user);
        tokenMap.put(name, token);
        
        System.out.println("目前線上使用者數:" + tokenMap.size());
        return token;
    }
}

Token 設計考量:

  • 包含時間戳確保每次登入 Token 不同,防止多人共用帳號
  • 採用 MD5 雜湊,不可逆且長度固定
  • 雙向 Map 結構支援快速查找與登出操作

4. 登入 Controller

import org.springframework.web.bind.annotation.*;

@Controller
@RequestMapping("/login")
public class LoginController {
    @Autowired
    private LoginService loginService;

    @UserAccess  // 示例用,實際登入不需驗證
    @RequestMapping(value="/loginin", method=RequestMethod.GET)
    @ResponseBody
    public String login(HttpServletRequest request) {
        String name = request.getParameter("name");
        String password = request.getParameter("password");
        return loginService.login(name, password);
    }
}

建議 Token 放在 Request Header 中,前後端分離架構下不影響既有參數處理邏輯。

5. AOP 權限驗證切面

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;

@Component
@Aspect
public class PermissionAspect {
    // 以 @UserAccess 註解為切入點
    @Before("@annotation(com.example.annotation.UserAccess)")
    public void checkPermission(JoinPoint joinPoint) throws Exception {
        System.out.println("前置通知:權限驗證開始");
        
        Object[] args = joinPoint.getArgs();
        HttpServletRequest request = (HttpServletRequest) args[0];
        String token = request.getParameter("token");
        
        System.out.println("驗證 Token:" + token);
        
        User user = LoginService.loginUserMap.get(token);
        if (user == null) {
            System.out.println("驗證失敗:Token 無效或已過期");
            throw new Exception("無權限存取");
        }
        
        System.out.println("驗證通過:使用者 " + user.getName());
    }
}

運作流程總結

  1. App 呼叫 /login/loginin 傳送帳密,取得 Token
  2. 後續 API 請求在 Header 或參數帶入 token=xxx
  3. 標註 @UserAccess 的方法執行前,AOP 自動攔截驗證
  4. Token 有效 → 繼續執行業務邏輯;無效 → 拋出例外阻擋

優點與延伸

  • 非侵入式:既有程式碼零修改,新功能僅需加註解
  • 彈性擴充:可延伸支援角色權限、IP 白名單、裝置綁定等
  • 生產環境建議:Token 改用 Redis 儲存並設定 TTL,支援分叢集部署

完整原始碼參考:GitHub 專案連結

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved