遗留的问题
- 1、点击切换验证码
- 2、1分钟后自动切换验证码
点击切换验证码
实现步骤:
- 1、点击事件
- 2、调用验证码接口
- 3、更新验证码的值
点击事件
给图片添加点击事件:
<img :src=" 'data:image/png;base64,' + captchaImg"
style="width: 100%; height: 50px; margin-top: 10px; cursor: pointer"
@click="refreshCaptcha">
调用验证码接口
const refreshCaptcha = async () => {
const captcha = await api.getCaptcha()
captchaKey.value = captcha.key
captchaImg.value = captcha.img
}
onMounted(async () => {
await refreshCaptcha()
})
1分钟后自动切换验证码
方案1
- 1、页面挂载的时候,创建定时器,和手动点击切换的逻辑不冲突
- 2、在页面卸载之前,销毁定时器
方案1:如果手动点击了,验证码的生效时间就不对了。
方案2:
- 1、在页面挂载的时候创建定时器
- 2、在页面卸载之前销毁定时器
- 3、在刷新验证码以后,重新生成定时器:销毁和重新创建
方案2比较靠谱。
实现代码:
// 点击手动刷新验证码
const clickRefreshCaptcha = async () => {
await refreshCaptcha()
if (autoRefreshTimer.value) {
clearInterval(autoRefreshTimer.value)
autoRefreshTimer.value = setInterval(async () => {
await refreshCaptcha()
}, refreshMillionSeconds)
}
}
// 刷新验证码
const refreshCaptcha = async () => {
const captcha = await api.getCaptcha()
captchaKey.value = captcha.key
captchaImg.value = captcha.img
}
// 生命周期函数:页面挂载
onMounted(async () => {
await refreshCaptcha() // 收到刷新定时器
autoRefreshTimer.value = setInterval(async () => { // 定时刷新验证码
await refreshCaptcha()
}, refreshMillionSeconds)
})
// 生命周期函数:页面卸载之前
onBeforeUnmount(async () => {
clearInterval(autoRefreshTimer.value) // 卸载自动刷新验证码的定时器
})
接下来要做什么
- 1、实现校验验证码的功能
- 2、验证码校验通过以后再校验的功能
校验验证码
封装校验验证码的方法
isCaptcha: async (key, code) => {
let ok = false
await axios({
method: "post",
url: `http://127.0.0.1:18888/zdppy_captcha`,
data: {key, code}
}).then(resp => {
if (resp.data && resp.data.data && resp.data.status && resp.data.code === 10000) {
if (resp.data.data.ok) {
ok = true
}
}
})
return ok
}
在校验登录之前先校验验证码
const ok = await api.isCaptcha(captchaKey.value, data.captcha);
if (!ok) {
// TODO: 验证码框架应该再被使用以后自动移除该key
alert("验证码错误,请刷新之后重试")
return
}
alert("验证码校验成功")
return
优化验证码框架
确保key只能被使用一次,更安全。
import zdppy_captcha as captcha
import zdppy_cache as cache
# 系统的验证码
key, code, img = captcha.get_base64(4)
print(key)
print(code)
print(img)
# cache_obj 只有有set方法就行
# 存储验证码
cache_obj = cache.Cache("tmp/.zdppy_captcha")
cache_obj.set(key, code)
# 用户的验证码
user_key = key
user_captcha = code
# 校验
v1 = captcha.is_captcha(cache_obj, user_key, user_captcha)
print(v1, v1 == True)
# 使用一次以后,就失效
v1 = captcha.is_captcha(cache_obj, user_key, user_captcha)
print(v1, v1 == False)
封装发送登录请求的方法
login: async (username, password) => {
let ok = false
await axios({
method: "post",
url: `http://127.0.0.1:18888/auth/user/login`,
data: {username, password}
}).then(resp => {
if (resp.data && resp.data.data && resp.data.status && resp.data.code === 10000) {
ok = true
} else {
message.error(resp.data.data.msg)
}
}).catch(err => {
message.error(err.message)
})
return ok
}
封装清空验证码的逻辑
// 点击登录
const onFinish = async (data) => {
// 校验验证码
let ok = await api.isCaptcha(captchaKey.value, data.captcha);
if (!ok) {
await clearCaptcha()
message.error("验证码错误")
return
}
// 发送登录请求
ok = await api.login(data.username, data.password)
if (ok) {
message.success("登录成功")
} else {
await clearCaptcha()
}
};
// 清空验证码
const clearCaptcha = async () => {
formState.captcha = ""
await clickRefreshCaptcha() // 模拟点击操作
}
登录成功的响应
完整登录方法
// 点击登录
const onFinish = async (data) => {
// 校验验证码
const ok = await api.isCaptcha(captchaKey.value, data.captcha);
if (!ok) {
await clearCaptcha()
message.error("验证码错误")
return
}
// 发送登录请求
const loginData = await api.login(data.username, data.password)
console.log("xxx登录信息:", loginData)
if (loginData) {
message.success("登录成功")
} else {
await clearCaptcha()
}
};
到这一步以后,登录完成一大半了。
遗留问题
- 1、登录以后跳转最近文档
- 2、如果用户没有登录应该自动跳转登录页面
- 3、如果用户的token校验失败,应该自动调整登录界面