整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

从构建分布式秒杀系统聊聊验证码

为了拦截大部分请求,秒杀案例前端引入了验证码。淘宝上很多人吐槽,等输入完秒杀活动结束了,对,结束了...... 当然了,验证码的真正作用是,有效拦截刷单操作,让羊毛党空手而归。

验证码

如果想学习Java工程化、高性能及分布式、深入浅出。微服务、Spring,MyBatis,Netty源码分析的朋友可以加我的Java高级交流:854630135,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给大家。

那么到底什么是验证码呢?验证码作为一种人机识别手段,其终极目的,就是区分正常人和机器的操作。我们常见的互联网注册、登录、发帖、领优惠券、投票等等应用场景,都有被机器刷造成各类损失的风险。

目前常见的验证码形式多为图片验证码,即数字、字母、文字、图片物体等形式的传统字符验证码。这类验证码看似简单易操作,但实际用户体验较差(参见12306网站),且随着OCR技术和打码平台的利用,图片比较容易被破解,被破解之后就形同虚设。

这里我们使用腾讯的智能人机安全验证码,告别传统验证码的单点防御,十道安全栅栏打造立体全面的安全验证,将黑产拒之门外。

场景

下面我们来瞅瞅验证码轻松解决了那些场景安全问题:

  • 登录注册,为你防护撞库攻击、阻止注册机批量注册
  • 活动秒杀,有效拦截刷单操作,让羊毛党空手而归
  • 点赞发帖,有效解决广告屠版、恶意灌水、刷票问题
  • 数据保护,防止自动机、爬虫盗取网页内容和数据

申请

申请地址:https://007.qq.com/product.html

在线体验:https://007.qq.com/online.html

只要一个QQ就可以免费申请,对于一般的企业OA系统或者个人博客网站,验证码免费套餐足够了已经,具备以下特点:

  • 2000次/小时安全防护
  • 支持免验证+分级验证
  • 三分钟快速接入
  • 全功能配置后台
  • 支持HTTPS
  • 阈值内流量无广告

2000次/小时的安全防护,一般很少达到如此效果,当然了即时超出阈值,顶多也就是多个广告而已。

接入

快读接入:https://007.qq.com/quick-start.html

接入与帮助提供了多种客户端和服务端的接入案例,这里我们使用我们秒杀案例中最熟悉的Java语言来接入。

前端

引入JS:

 <script src="https://ssl.captcha.qq.com/TCaptcha.js"></script>

页面元素:

<!--点击此元素会自动激活验证码,不一定是button,其他标签也可以-->
<!--id : 元素的id(必须)-->
<!--data-appid : AppID(必须)-->
<!--data-cbfn : 回调函数名(必须)-->
<!--data-biz-state : 业务自定义透传参数(可选)-->
<button id="TencentCaptcha"
 data-appid="*********"
 data-cbfn="callback">验证</button>

JS回调:

<script type="text/javascript">
 window.callback = function(res){
 console.log(res)
 // res(未通过验证)= {ret: 1, ticket: null}
 // res(验证成功) = {ret: 0, ticket: "String", randstr: "String"}
 if(res.ret === 0){
 startSeckill(res)
 }
 }
 //后台验证ticket,并进入秒杀队列
 function startSeckill(res){
 $.ajax({
 url : "startSeckill",
 type : 'post',
 data : {'ticket' : res.ticket,'randstr':res.randstr},
 success : function(result) {
 //验证是否通过,提示用户
 }
 });
 }
</script>

后端

@Api(tags = "秒杀商品")
@RestController
@RequestMapping("/seckillPage")
public class SeckillPageController {
 
 @Autowired
 private ActiveMQSender activeMQSender;
 //自定义工具类
 @Autowired
 private HttpClient httpClient;
 //这里自行配置参数
 @Value("${qq.captcha.url}")
 private String url;
 @Value("${qq.captcha.aid}")
 private String aid;
 @Value("${qq.captcha.AppSecretKey}")
 private String appSecretKey;
 
 @RequestMapping("/startSeckill")
 public Result startSeckill(String ticket,String randstr,HttpServletRequest request) {
 HttpMethod method =HttpMethod.POST;
 MultiValueMap<String, String> params= new LinkedMultiValueMap<String, String>();
 params.add("aid", aid);
 params.add("AppSecretKey", appSecretKey);
 params.add("Ticket", ticket);
 params.add("Randstr", randstr);
 params.add("UserIP", IPUtils.getIpAddr(request));
 String msg = httpClient.client(url,method,params);
 /**
 * response: 1:验证成功,0:验证失败,100:AppSecretKey参数校验错误[required]
 * evil_level:[0,100],恶意等级[optional]
 * err_msg:验证错误信息[optional]
 */
 //{"response":"1","evil_level":"0","err_msg":"OK"}
 JSONObject json = JSONObject.parseObject(msg);
 String response = (String) json.get("response");
 if("1".equals(response)){
 //进入队列、假数据而已
 Destination destination = new ActiveMQQueue("seckill.queue");
 activeMQSender.sendChannelMess(destination,1000+";"+1);
 return Result.ok();
 }else{
 return Result.error("验证失败");
 }
 }
}

自定义请求工具类 HttpClient:

如果想学习Java工程化、高性能及分布式、深入浅出。微服务、Spring,MyBatis,Netty源码分析的朋友可以加我的Java高级交流:854630135,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给大家。

@Service
public class HttpClient {
 public String client(String url, HttpMethod method, MultiValueMap<String, String> params){
 RestTemplate client = new RestTemplate();
 HttpHeaders headers = new HttpHeaders();
 // 请勿轻易改变此提交方式,大部分的情况下,提交方式都是表单提交
 headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
 HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<MultiValueMap<String, String>>(params, headers);
 // 执行HTTP请求
 ResponseEntity<String> response = client.exchange(url, HttpMethod.POST, requestEntity, String.class);
 return response.getBody();
 }
}

获取IP地址工具类 IPUtils :

/**
 * IP地址
 */
public class IPUtils {
 private static Logger logger = LoggerFactory.getLogger(IPUtils.class);
 /**
 * 获取IP地址
 * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
 * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
 */
 public static String getIpAddr(HttpServletRequest request) {
 String ip = null;
 try {
 ip = request.getHeader("x-forwarded-for");
 if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
 ip = request.getHeader("Proxy-Client-IP");
 }
 if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
 ip = request.getHeader("WL-Proxy-Client-IP");
 }
 if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
 ip = request.getHeader("HTTP_CLIENT_IP");
 }
 if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
 ip = request.getHeader("HTTP_X_FORWARDED_FOR");
 }
 if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
 ip = request.getRemoteAddr();
 }
 } catch (Exception e) {
 logger.error("IPUtils ERROR ", e);
 }
 // 使用代理,则获取第一个IP地址
 if (StringUtils.isEmpty(ip) && ip.length() > 15) {
 if (ip.indexOf(",") > 0) {
 ip = ip.substring(0, ip.indexOf(","));
 }
 }
 return ip;
 }
}

案例效果图

启动项目访问:http://localhost:8080/seckill/1000.shtml

定制接入

在系统登录的时候,我们需要先校验用户名以及密码,然后调用验证码操作,这里就需要我们定制接入了。

<!-- 项目中使用了Vue -->
<div class="log_btn" @click="login" >登录</div>
login: function () {
 //这里校验用户名以及密码
 // 直接生成一个验证码对象
 var captcha = new TencentCaptcha('2001344788', function(res) {
 if(res.ret === 0){//回调成功
 var data = {'username':username,'password':password,'ticket':res.ticket,'randstr':res.randstr}
 $.ajax({
 type: "POST",
 url: "sys/loginCaptcha",
 data: data,
 dataType: "json",
 success: function(result){
 //校验是否成功
 }
 });
 }
 });
 captcha.show(); // 显示验证码
},

后台监控

腾讯后台还提供了简单实用的数据监控,如下:

欢迎工作一到八年的Java工程师朋友们加入Java高级交流:854630135

本群提供免费的学习指导 架构资料 以及免费的解答

不懂得问题都可以在本群提出来 之后还会有直播平台和讲师直接交流噢

完小编前段时间发表的HTML学习之后,相信大家对网站建设与网页编写有了一定的初步了解,今天我们来开始介绍层叠样式表css,css是为HTML页面的排版美化而设计的,可以实现html无法设计的效果,一般是用来配合html来使用的,一般模式:选择器{属性:值}即selector{property:value}例如:body{corlor:red;font-size:12px;},他有三种引入方式:行内样式、内部样式表、外部样式表。

css三种嵌入方式:

一、行内样式

使用style属性引入CSS样式。

示例:

<h1 style="color:red;">style属性的应用</h1>

<p style="font-size:14px;color:green;">直接在HTML标签中设置的样式</p>

实际在写页面时不提倡使用,在测试的时候可以使用。

例如:

<!DOCTYPE> <html> <head> <meta charset="utf-8" /> <title>行内样式</title> </head> <body> <!--使用行内样式引入CSS--> <h1 style="color:red;">Leaping Above The Water</h1> <p style="color:red;font-size:30px;">我是p标签</p> </body> </html>

二、内部样式表

在style标签中书写CSS代码。style标签写在head标签中。

示例:

<head>

<style type="text/css">

h3{

color:red;

}

</style>

</head>

例如:<!DOCTYPE> <html> <head> <meta charset="utf-8" /> <title>内部样式表</title> <!--使用内部样式表引入CSS--> <style type="text/css"> div{ background: green; } </style> </head> <body> <div>我是DIV</div> </body> </html>

三、外部样式表

CSS代码保存在扩展名为.css的样式表中

HTML文件引用扩展名为.css的样式表,有两种方式:链接式、导入式。

语法:

1、链接式

<link type="text/css" rel="styleSheet" href="CSS文件路径" />

2、导入式

<style type="text/css">

@import url("css文件路径");

</style>

例如:<!DOCTYPE> <html> <head> <meta charset="utf-8" /> <title>外部样式表</title> <!--链接式:推荐使用--> <link rel="stylesheet" type="text/css" href="css/style.css" /> <!--导入式--> <style type="text/css"> @import url("css/style.css"); </style> </head> <body> <ol> <li>1111</li> <li>2222</li> </ol> </html>

行内样式>内部样式>外部样式(后两者是就近原则)。

css注释格式如下:

/* 注释如下*/

css中的颜色值表示如下:

可以是直接写英文单词,例如蓝色尽可以写blue;还可以写为十六进制字符,例如#rrggbb\#ffcc00,#rgb如:#fc0十六进制的颜色可以在颜色表中查询,这里我给大家提供一个,当然网上也有很多,大家也可以自己百度一下:

还有一种颜色的表示方式就是rbg模式,例如:

rgb(x,x,x) 其中x是一个0-255的整数值如:rgb(255,204,0)

rgb(x%,x%,x%) 其中x是一个0-100的整数值如rgb(100%,80%,0%)

Css的长度单位:

相对长度单位:px 像素(Pixel) em 相对于当前文本字体尺寸的倍数 % 百分比

绝对长度单位:in英寸(Inch) pt 点(Point) cm 厘米(Centimeter)mm 毫米(Millimeter)。

换算比例:1in = 2.54cm = 25.4 mm = 72pt

Css的七大类选择器:

标签选择器 例如:p{};

类选择器 例如.div{};(一个点加命名的类名)

Id选择器 例如 #div{};(斜体井号加ID名,ID是不可重复的,类可以相同)

通配符选择器:*{};

伪类选择器:

a:link{}没有访问时的链接;

a:visited{}已经访问过时的链接;

a:hove{}鼠标滑过时的链接;

a:active{}已经选中的链接;

:first-child{}为第一个字符设置样式;

:last-child{}为最后一个字符设置样式;

:nth-child(){}可以为指定字符设置样式

派生选择器(后代选择器、子元素选择器和相邻兄弟选择器):

后代选择器: 以空格分隔

div ul li {color:#0099cc;}

子元素选择器: 以>分隔

div >ul li

相邻兄弟选择器: 以+分隔

div + div ul li

最后一个就是组合选择器,以逗号隔开

h1, h2, h3, h4, h5, h6 { color: green }

好了,css基础就给大家介绍到这里,有什么不懂得地方可以给小编留言,如果您有什么好的建议也可以关注小编,我们共同学习,共同讨论,共同进步,接下来我们会介绍下css的属性,敬请期待吧

果想开发一个网站,除了要精通后端开发语言(如:php)外,还要精通HTML代码。那么,什么是HTML呢?HTML是一种超文本标记语言,它包含有众多的标签,我们可以通过这些标签,把不同的internet资源(如:文字、图片、视频、音频、表单等等)整合在一个统一的文档中,这就形成了我们可以看得见的网页。那么,HTML都有哪些常用的标签呢?

一、文档类型声明。

html5文档类型声明:<!doctype html>

html4文档类型声明:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

二、html主标签。

这个标签是html最外层的标签,所有其它的HTML标签都要放在这个标签的内部。

<html>

<head></head>

<body></body>

</html>

三、双标签和单标签。

在HTML标签中,有的标签是成双成对的,如:<html></html>(如下图);而有的标签是单个的,如:<hr>横线标签。

四、head头部标签。

head头部有以下几种常用标签:

meta:主要提供有关页面的元信息。

link:用来定义文档与外部资源的关系,最常用的是调用CSS样式文件。

title:页面标题的标签。

script:用来调用JS文件或JS代码。当然,script标签也可以在body主体中使用。

五、body主体标签。

1、块级标签。

块级标签的特性是:独自占有一行;标签的高与宽、边距可以修改;没有设置宽与高时,默认继承父标签。例如:


<div>div1</div>

<div>div2</div>

<style>

.aa1{ border:1px solid #000; width:150px; height:100px; margin:30px; }

.aa2{ border:1px solid #000; width:150px; height:100px; margin:30px; }

</style>


前端页面显示的效果如下图:

常用的块级标签有:div、h1、h2、h3、h4、h5、h6、hr、menu、ul、ol、li、dl、dt、dd、table、p、form 。

2、内联标签。

内联标签与块级标签不同,它不能独自占有一行,会与其它内联标签在同一样展示;内联标签的高与宽、上下边距是不能修改的,它里面的文字或图片有多高,它就是多高。例如如下代码:


<style>

.aa1{ border:1px solid #000; width:150px; height:100px; margin:30px; }

.aa2{ border:1px solid #000; width:150px; height:100px; margin:30px; }

</style>

<span>span1</span>

<span>span2</span>


CSS样式代码跟块级标签的例子是一样的,而显示的效果就不一样了,宽与高、上下边距没有效果。如下图:

常用的内联标签有:span、a、b、strong、i、em 。

3、内联块级标签。

内联块级标签,既有一些内联标签的特性,也有一些块级标签的特点:它不能独自占有一行,但是可以修改它的宽度和高度。例如下面这段代码:


<style>

.aa1{ border:1px solid #000; width:150px; height:100px; margin:30px; }

.aa2{ border:1px solid #000; width:150px; height:100px; margin:30px; }

</style>

<img src="w5.jpg" alt="">

<img src="w5.jpg" alt="">


CSS样式代码跟块级标签的那个例子仍然是一样的,图片的宽和高、上下边距修改成功,而2个图片不能独自占有一行,而是在同一行。如下图:

常用的内联块级标签有:img、input、textarea。

4、区域标签。

所谓区域标签,就是主要用来划分布局页面区域的。如:头部、主体内容、侧边栏、底部。这样划分的好处是:让页面布局更加清晰明了。

常用的区域标签有:header(头部)、footer(底部)、nav(导航)、aside(侧边栏)、section(主体)、article(独立内容)。

5、表单标签。

这个表单标签我们也是会经常用到的,如:登录网站的时候、提交数据的时候。如下图的评论表单:

​表单常用的标签有:form、input、select、option、textarea 。

以上就是我们开发网页时,会常用到的HTML标签。当然,HTML标签远不止这些,尤其是html5出来后,新增了许多的新标签。但是,有些标签在我们开发中很少用到,所以,这里就没有做相应的介绍。