一個不錯的基於Spring boot+Security+Redis+MySql實現權限登錄和反爬蟲的腳手架

介紹

一個基於Spring boot 2.4.2、JDK 1.8、Security、防惡意請求技術實現的前後端分離的腳手架,可以爲開發人員省去前期框架調研和搭建的成本。源碼在碼雲上。

軟件架構

  1. Spring boot 2.4.2
  2. JDK 1.8
  3. Security
  4. kk-anti-reptile(反爬蟲接口防刷組件)
  5. Redis(登錄用戶信息)
  6. MySQL
  7. MyBatis

安裝教程

  1. 克隆 本代碼到本地
  2. 修改application.yml配置,包含Mysql數據庫信息、Redis連接信息、kk-anti-reptile配置信息(不修改也可以,默認,詳細參數見:kk-anti-reptile
  3. 將項目other/SQL/中的腳本放到mysql中執行,初始化表結構
  4. 啓動項目
  5. 使用測試工具或者前端連接請求

使用說明

本示例在TestWebSecurity類中配置了Security前端登錄接口和退出登錄接口,如想自定義接口,請修改如下圖圈中的配置

application.yml 配置文件中kk-anti-reptile 部分配置如下:

# 惡意請求
anti:
  reptile:
    manager:
    # 激活惡意請求/反爬蟲配置
      enabled: true
    # 需要攔截的請求,多個以“,”分隔,或者直接在controller方法上添加@AntiReptile
    #  include-urls: ^/admin/.*$
      ua-rule:
      #允許linux系統訪問
        allowed-linux: true
        # 全局攔截,默認爲false,爲false時,需要配置上面的include-urls
      global-filter-mode: true

詳細參數請參見kk-anti-reptile

請求示例

登錄接口

請求鏈接

http://localhost:8099/auth/login

請求參數

username:admin password:1234

注意,此處需要使用表單提交,postman中如下:

響應參數

登錄成功返回參數如下:

{
    "code": "00000",
    "msg": "操作成功!",
    "data": {
        "token": "3aa72e4a-74b5-4542-9e56-e7f31ec5ce09",
        "permissions": [],
        "loginTime": 1611284216123
    }
}

其中,token的值就是前端需要在每次請求中在請求頭部傳遞到後端的參數

退出登錄接口

請求鏈接

http://localhost:8099/auth/logout

請求參數

請求頭部需要放置如下參數:

X-token:token的值

Postman中如下:

響應參數

{
    "code": "00000",
    "msg": "您已經退出登錄!"
}

正常接口

正常業務邏輯中調用的接口傳參

請求鏈接

http://localhost:8099/test/listOrientations

請求參數

header中必須帶有X-token參數,其他業務參數請寫在請求體中

Postman中如下:

正常響應參數(沒有超過反爬蟲預警)

{
    "code": "00000",
    "msg": "ddd"
}

被攔截的響應參數

當使用postman多次請求,請求超過閾值,將會返回驗證碼頁面(如果前端JQ請求,請參照kk-anti-reptile處理方式正常顯示驗證碼)




	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
	<title>kk-anti-reptile驗證</title>
	<script>
		function getXhr() {
            var xhr = null;
            try {
                xhr = new XMLHttpRequest();
            } catch (e) {
                try {
                    xhr = new ActiveXObject("Msxml2.XMLHTTP");
                } catch (e) {
                    xhr = new ActiveXObject("Microsoft.XMLHTTP");
                }
            }
            return xhr;
        }

        function refresh() {
            var xhr = getXhr();
            var verifyId = document.getElementById("verifyId").value;
            var baseUrl = document.getElementById("baseUrl").value;
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    var verifyObj = JSON.parse(xhr.responseText);
                    document.getElementById("verifyId").value = verifyObj.verifyId;
                    document.getElementById("verifyImg").src = verifyObj.verifyImgStr;
                }
            }
            xhr.open("POST", baseUrl + "/kk-anti-reptile/refresh?verifyId="+verifyId, "true");
            xhr.send();
        }

        function validate() {
            var elements = document.getElementById("verifyFrom");
            var formData = new FormData();
            for(var i = 0; i < elements.length; i++) {
                formData.append(elements[i].name, elements[i].value);
            }
            var baseUrl = document.getElementById("baseUrl").value;
            var xhr = getXhr();
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    var obj = JSON.parse(xhr.responseText);
                    if (obj.result == true) {
                        closeThisWindows();
                    } else {
                        alert("驗證碼填寫錯誤")
                    }
                }
            }
            xhr.open("POST", baseUrl + "/kk-anti-reptile/validate", "true");
            xhr.send(formData);
        }

        function closeThisWindows() {
            if (navigator.userAgent.indexOf("MSIE") > 0) {
                if (navigator.userAgent.indexOf("MSIE 6.0") > 0) {
                    window.opener = null;
                    window.close();
                } else {
                    window.open('', '_top');
                    window.top.close();
                }
            } else if (navigator.userAgent.indexOf("Firefox") > 0) {
                window.location.href = 'about:blank';
            } else if (navigator.userAgent.indexOf("AppleWebKit") > 0) {
                window.location.href = 'about:blank';
                window.close();
            } else {
                window.opener = null;
                window.open('', '_self', '');
                window.close();
            }
        }
	</script>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
	<title>普通驗證碼</title>

	<style>
		* {
			box-sizing: border-box;
			margin: 0;
			padding: 0;
		}

		form {
			width: 240px;
			margin: 100px auto;
			padding: 20px;
		}

		input[type="text"] {
			margin: 10px 0;
			padding: 0 4px;
			width: 100%;
			height: 32px;
			border: 1px solid #c3c3c3;
			border-radius: 4px;
		}

		input[type="button"] {
			width: 100%;
			height: 32px;
			color: #fff;
			background-color: #40a9ff;
			border-color: #40a9ff;
			border-radius: 4px;
			outline: 0;
			cursor: pointer;
			text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.12);
			box-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);
			border-style: none;
		}

		.img-wrapper {
			display: flex;
			align-items: center;
		}

		.img-wrapper img {
			width: 130px;
			height: 48px;
		}

		.img-wrapper a {
			text-decoration: none;
			color: #1890ff;
		}
	</style>




	<form id="verifyFrom" method="post" action="">
		<input type="hidden" id="baseUrl" name="baseUrl">
		<input type="hidden" id="verifyId" name="verifyId" value="d4eee0b1-b416-4231-96d8-8af6f70ad2c2">
		<input type="hidden" id="realRequestUri" name="realRequestUri" value="/test/listOrientations">
		<span>操作頻繁,請輸入驗證碼</span>
		<div class="img-wrapper">
			<img id="verifyImg" src="data:image/jpeg;base64,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"> &nbsp;&nbsp;&nbsp;&nbsp;
			<a href="javascript:void(0);" onclick="refresh()">刷新</a>
		</div>
		<input type="text" id="result" name="result">
		<br>
		<input type="button" value="確認" onclick="validate()">
</form>


讚賞我

  1. 如果您覺得這個不錯,可以打賞下作者,您的贊同是作者不懈努力的源泉

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章