Vue3+Vue-cli4專案中使用騰訊滑塊驗證碼
簡介:
滑塊驗證碼相比於傳統的圖片驗證碼具有以下優點:
- 驗證碼的具體驗證不需要服務端去驗證,服務端只需要核驗驗證結果即可。
- 驗證碼的實現不需要我們去了解,也不需要我們去具體實現。
- 滑塊驗證碼的安全程度相比於傳統驗證碼高不少。
- ...
由於網路上和騰訊api文件中缺少關於vue3中組合式api怎麼應用騰訊的滑塊驗證碼,所以出此教程。本人也非vue大佬,對vue的理解也不過停留在初級使用的程度上,有錯誤之處,敬請指出。
開始:
首先,我們需要去騰訊雲申請一個圖形驗證的api,使用場景中選擇自己的使用場景。完成步驟後我們會獲得CaptchaAppId和AppSecretKey。這兩個東西就是後面我們服務端核驗驗證結果的引數之二。
在Vue3中使用,首先需要在public資料夾的index.html中,引入騰訊驗證碼的js。
<script src="https://ssl.captcha.qq.com/TCaptcha.js"></script>
在需要用到滑塊驗證碼的元件中,為登陸的按鈕繫結方法。並且在表單物件中新增以下兩個欄位ticket
,randstr
。
我這裡示例是這樣寫的
export default {
name: "Login",
setup() {
const loginForm = reactive({
accountName: '',
accountPassword: '',
ticket: '',
randstr: ''
})
return {
loginForm
}
}
}
登陸按鈕繫結方法
export default {
name: "Login",
setup() {
const loginForm = reactive({
accountName: '',
accountPassword: '',
ticket: '',
randstr: ''
})
const loginPost = () => {
let captcha = new window.TencentCaptcha(config.app_id, res => {
loginForm.randstr = res.randstr;
loginForm.ticket = res.ticket;
userLogin(loginForm).then(resp => {
if (resp.code === 200) {
//登陸成功後的邏輯
} else {
//登陸失敗後的邏輯
}
}).catch(() => {
ElMessage.error({
message: '系統發生錯誤!請稍後重試!'
})
})
})
captcha.show();
}
return {
loginPost,
loginForm
}
}
}
以上是在vue中寫的程式碼,但是這裡只實現了使用者完成驗證碼的操作,具體的最終判斷邏輯必須要在我們後端實現。我們後端就用Springboot來實現核驗操作。
首先要引入騰訊sdk的maven依賴
<!-- 騰訊SDK-滑塊驗證碼依賴-->
<dependency>
<groupId>com.tencentcloudapi</groupId>
<artifactId>tencentcloud-sdk-java</artifactId>
<version>4.0.11</version>
</dependency>
我們在utils包中新建一個類。
public class DescribeCaptchaResult {
@Value("${Tencent.SecretId}")
private String secretId;
@Value("${Tencent.SecretKey}")
private String secretKey;
@Value("${Tencent.CaptchaAppId}")
private int captchaAppId;
@Value("${Tencent.AppSecretKey}")
private String appSecretKey;
public JSONObject getTencentCaptchaResult(String ticket, String randstr, String userIp) {
try {
// 例項化一個認證物件,入參需要傳入騰訊雲賬戶secretId,secretKey,此處還需注意金鑰對的保密
// 金鑰可前往https://console.cloud.tencent.com/cam/capi網站進行獲取
Credential cred = new Credential(secretId, secretKey);
// 例項化一個http選項,可選的,沒有特殊需求可以跳過
HttpProfile httpProfile = new HttpProfile();
httpProfile.setEndpoint("captcha.tencentcloudapi.com");
// 例項化一個client選項,可選的,沒有特殊需求可以跳過
ClientProfile clientProfile = new ClientProfile();
clientProfile.setHttpProfile(httpProfile);
// 例項化要請求產品的client物件,clientProfile是可選的
CaptchaClient client = new CaptchaClient(cred, "", clientProfile);
// 例項化一個請求物件,每個介面都會對應一個request物件
DescribeCaptchaResultRequest req = new DescribeCaptchaResultRequest();
req.setCaptchaType(9L);
req.setTicket(ticket);
req.setRandstr(randstr);
req.setUserIp(userIp);
req.setCaptchaAppId((long) captchaAppId);
req.setAppSecretKey(appSecretKey);
// 返回的resp是一個DescribeCaptchaResultResponse的例項,與請求物件對應
DescribeCaptchaResultResponse resp = client.DescribeCaptchaResult(req);
// 輸出json格式的字串回包
return JSONObject.parseObject(DescribeCaptchaResultResponse.toJsonString(resp));
} catch (TencentCloudSDKException e) {
throw new ServiceException(e.getMessage());
}
}
}
下面解析一下該類需要的引數。
引數 | 解析 |
---|---|
secretId | SecretId為你騰訊雲賬號的Api金鑰ID(推薦使用子賬號,授權) |
secretKey | SecretKey為你騰訊雲賬號的Api金鑰Key(推薦使用子賬號,授權) |
captchaAppId | captchaAppId為你申請的騰訊驗證碼api金鑰 |
appSecretKey | appSecretKey為你申請的騰訊驗證碼api金鑰 |
ticket | ticket為你前端滑塊驗證碼驗證後返回的引數 |
randstr | randstr你前端滑塊驗證碼驗證後返回的引數 |
userIp | userIp為你業務層獲取的Ip |
提供引數傳送之後,會返回一個DescribeCaptchaResultResponse型別的資料,我們將他轉為FastJson的JSONObject型別進行解析。返回資料結構如下:
{
"Response": {
"RequestId": "3b61a17b-cb38-470e-802c-b6242faf81ac",
"CaptchaCode": 1,
"CaptchaMsg": "OK",
"EvilLevel": 0,
"GetCaptchaTime": 1583749870
},
"retcode": 0,
"retmsg": "success"
}
具體其他引數可以參考騰訊api文件:https://cloud.tencent.com/document/product/1110/36926
我這裡讀取CaptchaCode的值,如果值為1則是驗證碼驗證成功,不為1則是驗證失敗。
//核驗驗證碼
JSONObject tencentCaptchaResult = captchaResult.getTencentCaptchaResult(ticket, randstr, clientIp);
int captchaCode = Integer.parseInt(tencentCaptchaResult.getString("CaptchaCode"));
if (captchaCode != 1) {
throw new ServiceException("驗證碼錯誤!");
}
//...後續業務邏輯
後續
在騰訊雲中還能為驗證碼設定更多的東西,如驗證碼的主題,驗證碼的場景配置,驗證碼惡意攔截的等級等等。。
在後臺也能看到驗證碼的請求量
我感覺後端和前端還可以再封裝一下,讓程式碼更加簡潔。阿里雲還有其他的新型驗證碼還沒有嘗試,我個人是感覺騰訊驗證碼使用起來是挺好的,但是api文件什麼的有點差了,資料也很少。