🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

if-captcha

Package Overview
Dependencies
Maintainers
1
Versions
26
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

if-captcha - npm Package Compare versions

Comparing version
2.0.12
to
2.0.13
+1
-1
package.json
{
"name": "if-captcha",
"version": "2.0.12",
"version": "2.0.13",
"description": "安全验证滑块服务插件(Vue2/Vue3)",

@@ -5,0 +5,0 @@ "main": "./src/components/index.js",

@@ -70,3 +70,2 @@ ## 如何使用

## Todo

@@ -92,2 +91,49 @@ ### captchaGetUrl 支持 Promise对象

}
}
}
### 示例
```
let res = await $ifCaptcha.verify({
captchaType: 'blockPuzzle',
/**
劫持请求
payload {captchaType: 'blockPuzzle'} 模块抛出的参数
format(success:boolean, data) 对返回结果进行格式化
*/
captchaGetUrl: async (payload, format) => {
// 自定义逻辑
let res = await request('https://uc-uat.ifyou.net/uc/api/captcha/get', payload)
let success = res.repCode == '0000'
// 对于clickWord类型 需要如下参数 originalImageBase64, token, secretKey, wordList
const { jigsawImageBase64, originalImageBase64, secretKey, token } = res.repData
let data = {
jigsawImageBase64,
originalImageBase64,
secretKey,
token
}
// 自定义逻辑结束 !!!注意data结构, 这是模块可以识别的结构
return format(success, data)
},
captchaCheckUrl: async (payload, format) => {
/** 自定义逻辑 */
let params = { ...payload, foo: 'Hi, World', noise: { env: 'demo', ver: '1.0' } }
let res = await request('https://uc-uat.ifyou.net/uc/api/captcha/check', params)
let success = res.repCode == '0000'
/** 自定义逻辑结束 */
return format(success)
}
});
if (res) {
console.log(JSON.stringify(res))
} else {
result.value = '验证失败'
}
```

@@ -15,4 +15,4 @@ <template>

:explain="options.explain" :imgSize="options.imgSize" :blockSize="options.blockSize"
:barSize="options.barSize" :captchaGetUrl="options.captchaGetUrl" :captchaCheckUrl="options.captchaCheckUrl" :params="options.params"
ref="instance"></component>
:barSize="options.barSize" :captchaGetUrl="options.captchaGetUrl" :captchaCheckUrl="options.captchaCheckUrl"
:params="options.params" ref="instance"></component>
</div>

@@ -74,7 +74,7 @@ </div>

captchaGetUrl: {
type: String,
type: [String, Function],
default: '/captcha/get'
},
captchaCheckUrl: {
type: String,
type: [String, Function],
default: '/captcha/check'

@@ -99,3 +99,3 @@ }

mounted() {
const { captchaType, mode, vSpace, explain, imgSize, blockSize, barSize, isShow, captchaGetUrl, captchaCheckUrl, params={}} = this;
const { captchaType, mode, vSpace, explain, imgSize, blockSize, barSize, isShow, captchaGetUrl, captchaCheckUrl, params = {} } = this;
Object.assign(this.options, { captchaType, mode, vSpace, explain, imgSize, blockSize, barSize, isShow, captchaGetUrl, captchaCheckUrl, params });

@@ -102,0 +102,0 @@ },

<template>
<div style="position: relative">
<div class="verify-img-out">
<div class="verify-img-panel" :style="{
width: setSize.imgWidth,
height: setSize.imgHeight,
'background-size': setSize.imgWidth + ' ' + setSize.imgHeight,
'margin-bottom': vSpace + 'px',
}">
<div class="verify-refresh" style="z-index: 3" @click="refresh" v-show="showRefresh">
<i class="captcha-icon-refresh"></i>
</div>
<img :src="'data:image/png;base64,' + pointBackImgBase" ref="canvas" alt=""
style="width: 100%; height: 100%; display: block" @click="bindingClick ? canvasClick($event) : undefined" />
<div v-if="!loading && !error">
<div class="verify-img-out">
<div class="verify-img-panel" :style="{
width: setSize.imgWidth,
height: setSize.imgHeight,
'background-size': setSize.imgWidth + ' ' + setSize.imgHeight,
'margin-bottom': vSpace + 'px',
}">
<div class="verify-refresh" style="z-index: 3" @click="refresh" v-show="showRefresh">
<i class="captcha-icon-refresh"></i>
</div>
<img :src="'data:image/png;base64,' + pointBackImgBase" ref="canvas" alt=""
style="width: 100%; height: 100%; display: block" @click="bindingClick ? canvasClick($event) : undefined" />
<div v-for="(tempPoint, index) in tempPoints" :key="index" class="point-area" :style="{
'background-color': '#1abd6c',
color: '#fff',
'z-index': 9999,
width: '20px',
height: '20px',
'text-align': 'center',
'line-height': '20px',
'border-radius': '50%',
position: 'absolute',
top: parseInt(tempPoint.y - 10) + 'px',
left: parseInt(tempPoint.x - 10) + 'px',
}">
{{ index + 1 }}
<div v-for="(tempPoint, index) in tempPoints" :key="index" class="point-area" :style="{
'background-color': '#1abd6c',
color: '#fff',
'z-index': 9999,
width: '20px',
height: '20px',
'text-align': 'center',
'line-height': '20px',
'border-radius': '50%',
position: 'absolute',
top: parseInt(tempPoint.y - 10) + 'px',
left: parseInt(tempPoint.x - 10) + 'px',
}">
{{ index + 1 }}
</div>
</div>
</div>
<!-- 'height': this.barSize.height, -->
<div class="verify-bar-area" :style="{
width: setSize.imgWidth,
color: this.barAreaColor,
'border-color': this.barAreaBorderColor,
'line-height': this.barSize.height,
}">
<span class="verify-msg">{{ text }}</span>
</div>
</div>
<!-- 'height': this.barSize.height, -->
<div class="verify-bar-area" :style="{
width: setSize.imgWidth,
color: this.barAreaColor,
'border-color': this.barAreaBorderColor,
'line-height': this.barSize.height,
}">
<span class="verify-msg">{{ text }}</span>
<div v-else-if="!error">
<div style="text-align: center">
<i class="captcha-icon-refresh captcha-spin" style="opacity:.85"></i>
<div style="color:#999; margin-top: 10px; font-size: 14px;">加载中...</div>
</div>
</div>
<div v-else>
<div style="text-align: center">
<div style="font-size:14px; color:#f30; margin: 20px auto;">数据获取错误:无法获取安全验证信息</div>
<a href="javascript:void(0)" @click="refresh">点击重新获取</a>
</div>
</div>
</div>

@@ -93,7 +108,7 @@ </template>

captchaGetUrl: {
type: String,
type: [String, Function],
default: '/captcha/get'
},
captchaCheckUrl: {
type: String,
type: [String, Function],
default: '/captcha/check'

@@ -129,2 +144,4 @@ },

canvas: null,
loading: true,
error: null,
};

@@ -140,3 +157,11 @@ },

methods: {
init() {
responseFormat(success, data, error = '请求失败') {
return {
repCode: !!success ? '0000' : '6111',
repData: data,
repMsg: error
}
},
async init() {
//加载页面

@@ -146,3 +171,3 @@ this.fontPos.splice(0, this.fontPos.length);

this.num = 1;
this.getPictrue();
await this.getPictrue();
this.$nextTick(() => {

@@ -172,3 +197,3 @@ let { imgHeight, imgWidth, barHeight, barWidth } = resetSize(this);

//等创建坐标执行完
setTimeout(() => {
setTimeout(async () => {
// var flag = this.comparePos(this.fontPos, this.checkPosArr);

@@ -188,7 +213,22 @@ //发送后端请求

token: this.backToken,
params: this.params
...this.params
};
request(this.captchaCheckUrl, data)
.then((res) => {
if (res.repCode == "0000") {
let res;
try {
if(typeof this.captchaCheckUrl === 'string') {
res = await request(this.captchaCheckUrl, data)
} else if(typeof this.captchaCheckUrl === 'function') {
res = await this.captchaCheckUrl(data, this.responseFormat)
if(!res.repCode) {
let errorMsg = 'captchaCheckUrl必须返回{repCode}'
console.error(errorMsg)
throw new Error(errorMsg)
}
} else {
let errorMsg = 'captchaCheckUrl不是字符串或者函数'
console.error(errorMsg)
throw new Error(errorMsg)
}
if (res.repCode == "0000") {
this.barAreaColor = "#4cae4c";

@@ -215,6 +255,8 @@ this.barAreaBorderColor = "#5cb85c";

}
})
.catch((e) => {
this.$parent.$emit("error", e);
});
} catch(e) {
this.$parent.$emit("error", e);
} finally {
//
}
}, 400);

@@ -237,3 +279,3 @@ }

refresh() {
async refresh() {
this.tempPoints.splice(0, this.tempPoints.length);

@@ -246,25 +288,44 @@ this.barAreaColor = "#000";

this.num = 1;
this.getPictrue();
await this.getPictrue();
this.text = "验证失败";
this.showRefresh = true;
},
getPictrue() {
async getPictrue() {
const { captchaType } = this;
request(this.captchaGetUrl, { captchaType })
.then((res) => {
const { repCode, repData, repMsg } = res;
if (repCode == "0000") {
const { originalImageBase64, token, secretKey, wordList } = repData;
this.pointBackImgBase = originalImageBase64;
this.backToken = token;
this.secretKey = secretKey;
this.poinTextList = wordList;
this.text = "请依次点击【" + wordList.join(",") + "】";
} else {
this.text = repMsg;
this.loading = true;
this.error = null
let res;
try {
if (typeof this.captchaGetUrl === 'string') {
res = await request(this.captchaGetUrl, { captchaType })
} else if (typeof this.captchaGetUrl === 'function') {
res = await this.captchaGetUrl({ captchaType }, this.responseFormat)
if (!res.repCode || !res.repData) {
let errorMsg = 'captchaGetUrl必须返回{repCode, repData, repMsg?}'
console.error(errorMsg)
throw new Error(errorMsg)
}
})
.catch((e) => {
this.$parent.$emit("error", e);
});
} else {
let errorMsg = 'captchaGetUrl不是字符串或者函数'
console.error(errorMsg)
throw new Error(errorMsg)
}
const { repCode, repData, repMsg } = res;
if (repCode == "0000") {
const { originalImageBase64, token, secretKey, wordList } = repData;
this.pointBackImgBase = originalImageBase64;
this.backToken = token;
this.secretKey = secretKey;
this.poinTextList = wordList;
this.text = "请依次点击【" + wordList.join(",") + "】";
} else {
this.text = repMsg;
}
} catch (e) {
this.$parent.$emit("error", e);
} finally {
this.loading = false
}
},

@@ -271,0 +332,0 @@

@@ -130,7 +130,7 @@ <template>

captchaGetUrl: {
type: String,
type: [String, Function],
default: '/captcha/get'
},
captchaCheckUrl: {
type: String,
type: [String, Function],
default: '/captcha/check'

@@ -145,3 +145,3 @@ },

return {
loading: false,
loading: true,
error: null,

@@ -197,27 +197,53 @@ secretKey: "", //后端返回的ase加密,

methods: {
responseFormat(success, data, error = '请求失败'){
return {
repCode: !!success ? '0000' : '6111',
repData: data,
repMsg: error
}
},
// 请求背景图片和验证图片
getPictrue() {
async getPictrue() {
const { captchaType } = this;
this.loading = true;
this.error = null
request(this.captchaGetUrl, { captchaType })
.then((res) => {
const { repCode, repData, repMsg } = res;
if (repCode == "0000") {
const { originalImageBase64, jigsawImageBase64, token, secretKey } =
repData;
this.backImgBase = originalImageBase64;
this.blockBackImgBase = jigsawImageBase64;
this.backToken = token;
this.secretKey = secretKey;
} else {
this.tipWords = repMsg;
try {
let res;
if(typeof this.captchaGetUrl === 'string') {
res = await request(this.captchaGetUrl, { captchaType })
} else if(typeof this.captchaGetUrl === 'function') {
res = await this.captchaGetUrl({captchaType}, this.responseFormat)
if(!res.repCode || !res.repData) {
let errorMsg = 'captchaGetUrl必须返回{repCode, repData, repMsg?}'
console.error(errorMsg)
throw new Error(errorMsg)
}
})
.catch((e) => {
} else {
let errorMsg = 'captchaGetUrl不是字符串或者函数'
console.error(errorMsg)
throw new Error(errorMsg)
}
const { repCode, repData, repMsg } = res;
if (repCode == "0000") {
const { originalImageBase64, jigsawImageBase64, token, secretKey } =
repData;
this.backImgBase = originalImageBase64;
this.blockBackImgBase = jigsawImageBase64;
this.backToken = token;
this.secretKey = secretKey;
} else {
this.error = '无法获取安全验证信息';
this.$parent.$emit("error", e);
}).finally(() => {
this.loading = false
});
this.tipWords = repMsg;
}
} catch(e) {
this.error = '无法获取安全验证信息';
this.$parent.$emit("error", e);
} finally {
this.loading = false
}
},

@@ -241,5 +267,5 @@

init() {
async init() {
this.text = this.explain;
this.getPictrue();
await this.getPictrue();
this.$nextTick(() => {

@@ -317,3 +343,3 @@ let { imgHeight, imgWidth, barHeight, barWidth } = resetSize(this);

end() {
async end() {
this.endMovetime = +new Date();

@@ -336,8 +362,24 @@ //判断是否重合

token: this.backToken,
params: this.params
...this.params
};
request(this.captchaCheckUrl, data)
.then((res) => {
if (res.repCode == "0000") {
let res;
try {
if(typeof this.captchaCheckUrl === 'string') {
res = await request(this.captchaCheckUrl, data)
} else if(typeof this.captchaCheckUrl === 'function') {
res = await this.captchaCheckUrl(data, this.responseFormat)
if(!res.repCode) {
let errorMsg = 'captchaCheckUrl必须返回{repCode}'
console.error(errorMsg)
throw new Error(errorMsg)
}
} else {
let errorMsg = 'captchaCheckUrl不是字符串或者函数'
console.error(errorMsg)
throw new Error(errorMsg)
}
if (res.repCode == "0000") {
this.moveBlockBackgroundColor = "#5cb85c";

@@ -391,11 +433,11 @@ this.leftBarBorderColor = "#5cb85c";

}
})
.catch((e) => {
this.$parent.$emit("error", e);
this.refresh();
});
this.status = false;
} catch(e) {
this.$parent.$emit("error", e);
this.refresh();
} finally {
this.status = false;
}
}
},
refresh() {
async refresh() {
this.$el.style.pointerEvents = 'auto'

@@ -417,3 +459,3 @@ this.showRefresh = true;

this.getPictrue();
await this.getPictrue();
setTimeout(() => {

@@ -420,0 +462,0 @@ this.transitionWidth = "";