更新时间:2021年2月22日
今天来实现一个难点
验证码问题
普通的版本就是生成是一个图片,让你输入数字
但是要作为我的毕业设计,那肯定不够
要用就用高级的操作
滑动验证码+选择文字验证码
高级验证码:
我曾经想过,是不是花点钱买第三方的验证码API
当我看到腾讯云的费用是1000起步的时候,我放弃了。。。
借鉴github的源码,我们自己弄一套出来
后端:
common新建2个处理验证码的工具类
依赖注入,这里不用接口
在处理登入控制器中添加API
[HttpGet]
[Route("/VerificationCodeImage")]
public async Task<IActionResult> GetVerificationCodeImage()
{
var model = await VerificationCodeImage.CreateHanZi();
var json_Model = Newtonsoft.Json.JsonConvert.SerializeObject(model.point_X_Y);
string pointBase64str = this._verificationCodeAESHelp.AES_Encrypt_Return_Base64String(json_Model);
this._verificationCodeAESHelp.SetCookie(VerificationCodeAESHelp._YZM, pointBase64str, 5);
string msg = "请根据顺序点击【" + string.Join("", model.point_X_Y.Select(x => x.Word).ToList()) + "】";
return Json(new { result = model.ImageBase64Str, msg = msg, code = 200 });
}
[Route("/verification/check")]
[HttpPost]
public IActionResult CheckCode([FromForm]string code)
{
try
{
var pointList = new List<Point_X_Y>();
try
{
pointList = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Point_X_Y>>(code);
}
catch (Exception)
{
return Json(new { msg = "验证失败!", status = "error", code = 200 });
}
if (pointList.Count != 2)
return Json(new { msg = "验证失败!", status = "error", code = 200 });
var _cookie = this._verificationCodeAESHelp.GetCookie(VerificationCodeAESHelp._YZM);
if (string.IsNullOrEmpty(_cookie))
return Json(new { msg = "验证失败!", status = "error", code = 200 });
string _str = this._verificationCodeAESHelp.AES_Decrypt_Return_String(_cookie);
var _cookiesPointList = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Point_X_Y>>(_str);
_cookiesPointList = _cookiesPointList.OrderBy(x => x.Sort).ToList();
int i = 0;
foreach (var item in pointList.AsParallel())
{
int _x = _cookiesPointList[i]._X - item._X;
int _y = _cookiesPointList[i]._Y - item._Y;
_x = Math.Abs(_x);
_y = Math.Abs(_y);
if (_x > 25 || _y > 25)
{
return Json(new { msg = "验证失败!", status = "error", code = 200 });
}
i++;
}
SlideVerifyCode(true);
}
catch (Exception)
{
}
string token = Guid.NewGuid().ToString();
HttpContext.Session.SetString("token", token);
return Json(new { msg = "验证通过!", status = "ok",code=200,token= token });
}
/// <summary>
/// 登陆
/// </summary>
/// <param name="userName"></param>
/// <param name="password"></param>
/// <returns></returns>
private (bool, string) VerifyValiate()
{
try
{
var _cookie = this._verificationCodeAESHelp.GetCookie(VerificationCodeAESHelp._SlideCode);
if (string.IsNullOrEmpty(_cookie))
{
SlideVerifyCode();
return (false, "请拖动滑块!");
}
string _str = this._verificationCodeAESHelp.AES_Decrypt_Return_String(_cookie);
var sildeCodeModel = Newtonsoft.Json.JsonConvert.DeserializeObject<SlideVerifyCodeModel>(_str);
if (!sildeCodeModel.SlideCode)
return (false, "请拖动滑块后点击汉字!");
var _NowTime = DateTime.Now;
var _time = sildeCodeModel.timestamp;
var number = (_NowTime - _time).Minutes;
if (number > 5)
{
SlideVerifyCode();
return (false, "滑块验证码过期!");
}
}
catch (Exception)
{
return (false, "滑动验证码失败!");
}
return (true, "");
}
private void SlideVerifyCode(bool _bool = false)
{
var json = Newtonsoft.Json.JsonConvert.SerializeObject(new SlideVerifyCodeModel() { SlideCode = _bool });
string base64Str = this._verificationCodeAESHelp.AES_Encrypt_Return_Base64String(json);
this._verificationCodeAESHelp.SetCookie(VerificationCodeAESHelp._SlideCode, base64Str, 10);
}
一个是前端访问后端给它一个图片,一个是前端将数据提交给我们后端进行处理
前端:
导入外部css和外部js
css和以前是一样的,但是js我们是要使用es6版本
我们要进行改造:
定义一个方法,接收这个下面的立即执行函数
模块导出
js调用,并且执行:
css调用:
然后细节该改的就改
运行测试:
这里为了能把验证码提交给后端验证,我们需要后端分配它一个token
后端代码:
处理登入,多一步,还要把token进行对比
[HttpPost]
public async Task<IActionResult> Login([FromForm] string username, [FromForm] string pwd,[FromForm] string token)//处理登录模块
{
if (token == null)
{
return Content(JsonFactory.Json(message: "请输入验证码", flag: false));
}
else
{
if (HttpContext.Session.GetString("token") == token)
{
var studentData = await _studentBll.GetEntities(u => u.student_username == username).FirstOrDefaultAsync();
if (studentData != null)
{
if (studentData.student_password == pwd)
{
HttpContext.Session.SetString("studentId", studentData.id.ToString());
return Content(JsonFactory.Json(message: "欢迎同学!" + studentData.student_name, data: 0));//学生登入成功
}
}
else
{
var teacherData = await _teacherBll.GetEntities(u => u.teacher_username == username).FirstOrDefaultAsync();
if (teacherData != null)
{
if (teacherData.teacher_password == pwd)
{
HttpContext.Session.SetString("teacherId", teacherData.id.ToString());
return Content(JsonFactory.Json(message: "欢迎教师!" + teacherData.teacher_name, data: 1));//教师登入成功
}
}
}
}
else
{
return Content(JsonFactory.Json(message: "验证码有误,请重新输入", flag: false));
}
}
return Content(JsonFactory.Json(message: "用户名或者密码错误", flag: false));
}
当验证码提交给我们的时候,我们也要给前端一个token:
[Route("/verification/check")]
[HttpPost]
public IActionResult CheckCode([FromForm]string code)
{
try
{
var pointList = new List<Point_X_Y>();
try
{
pointList = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Point_X_Y>>(code);
}
catch (Exception)
{
return Json(new { msg = "验证失败!", status = "error", code = 200 });
}
if (pointList.Count != 2)
return Json(new { msg = "验证失败!", status = "error", code = 200 });
var _cookie = this._verificationCodeAESHelp.GetCookie(VerificationCodeAESHelp._YZM);
if (string.IsNullOrEmpty(_cookie))
return Json(new { msg = "验证失败!", status = "error", code = 200 });
string _str = this._verificationCodeAESHelp.AES_Decrypt_Return_String(_cookie);
var _cookiesPointList = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Point_X_Y>>(_str);
_cookiesPointList = _cookiesPointList.OrderBy(x => x.Sort).ToList();
int i = 0;
foreach (var item in pointList.AsParallel())
{
int _x = _cookiesPointList[i]._X - item._X;
int _y = _cookiesPointList[i]._Y - item._Y;
_x = Math.Abs(_x);
_y = Math.Abs(_y);
if (_x > 25 || _y > 25)
{
return Json(new { msg = "验证失败!", status = "error", code = 200 });
}
i++;
}
SlideVerifyCode(true);
}
catch (Exception)
{
}
string token = Guid.NewGuid().ToString();
HttpContext.Session.SetString("token", token);
return Json(new { msg = "验证通过!", status = "ok",code=200,token= token });
}
前端:
现在,这个高级验证码的功能也算是完成了
很舒服!
下一步,就是和邮箱有关系了,进行注册和忘记密码的操作
再之后,就是和统计数据模块
我们的整个毕业设计的产品,就差不多要告一段落了。。。