之前公司写图片验证码时用的是session

后来写接口时也想用session存验证码  不过领导说RESTful API 写接口 没有session这一说 于是就用了redis 存验证码

还有就是接口需要返回值

不能直接把图片显示出来 这时需要对图片验证码进行base64转码处理 返回base64的值 然后他们前端再调用

===================================================================================================================

在Thinkphp框架里找了个验证码类 修改了一下

生成验证码(字体文件可以去thinkphp框架里提取):

<?php
/**
*@descrption : 验证码生成类
*@author : Mark.liu
*/ date_default_timezone_set('PRC');
require_once('/data/redis/RedisConfig.php'); class Verify {
protected $config = array(
'seKey' => '888888', // 验证码加密密钥
'codeSet' => '2345678abcdefhijkmnpqrstuvwxyzABCDEFGHJKLMNPQRTUVWXY', // 验证码字符集合
'expire' => 1800, // 验证码过期时间(s)
'useZh' => false, // 使用中文验证码
'zhSet' => '', // 中文验证码字符串
'useImgBg' => false, // 使用背景图片
'fontSize' => 25, // 验证码字体大小(px)
'useCurve' => true, // 是否画混淆曲线
'useNoise' => true, // 是否添加杂点
'imageH' => 0, // 验证码图片高度
'imageW' => 0, // 验证码图片宽度
'length' => 5, // 验证码位数
'fontttf' => '', // 验证码字体,不设置随机获取
'bg' => array(243, 251, 254), // 背景颜色
'reset' => true, // 验证成功后是否重置
); private $_image = NULL; // 验证码图片实例
private $_color = NULL; // 验证码字体颜色 /**
* 架构方法 设置参数
* @access public
* @param array $config 配置参数
*/
public function __construct($config=array()){
$this->config = array_merge($this->config, $config);
} /**
* 使用 $this->name 获取配置
* @access public
* @param string $name 配置名称
* @return multitype 配置值
*/
public function __get($name) {
return $this->config[$name];
} /**
* 设置验证码配置
* @access public
* @param string $name 配置名称
* @param string $value 配置值
* @return void
*/
public function __set($name,$value){
if(isset($this->config[$name])) {
$this->config[$name] = $value;
}
} /**
* 检查配置
* @access public
* @param string $name 配置名称
* @return bool
*/
public function __isset($name){
return isset($this->config[$name]);
} /**
* redis连接
* @return
*/ public function _redis()
{
$redis = new Redis;
$hosts = RedisServerConfig::SERVER_HOST;
$port = RedisServerConfig::SERVER_PORT;
$pwd = RedisServerConfig::SERVER_PASS;
$redis->connect($hosts,$port);
$redis->auth($pwd);
return $redis;
} /**
* 验证验证码是否正确
* @access public
* @param string $code 用户验证码
* @param string $id 验证码标识
* @return bool 用户验证码是否正确
*/
public function check($code, $id = '') {
$key = $this->authcode($this->seKey).$id; $redis = $this->_redis(); $_val = $redis->get($key); if(empty($_val))
{
return false;
} $secode = json_decode($_val,true); if(empty($code) || empty($secode)) {
return false;
} // session 过期
$NOW_TIME = time(); if($NOW_TIME - $secode['verify_time'] > $this->expire) { // unset($_SESSION[$key]);
$redis->expire($key,0);
// session($key, null); return false;
} if($this->authcode(strtoupper($code)) == $secode['verify_code']) {
// $this->reset && session($key, null);
// unset($_SESSION[$key]);
$redis->expire($key,0);
return true;
} return false;
} /**
* 输出验证码并把验证码的值保存的session中
* 验证码保存到session的格式为: array('verify_code' => '验证码值', 'verify_time' => '验证码创建时间');
* @access public
* @param string $id 要生成验证码的标识
* @return void
*/
public function entry($id = '') { // 图片宽(px)
$this->imageW || $this->imageW = $this->length*$this->fontSize*1.5 + $this->length*$this->fontSize/2;
// 图片高(px)
$this->imageH || $this->imageH = $this->fontSize * 2.5; // 建立一幅 $this->imageW x $this->imageH 的图像
$this->_image = imagecreate($this->imageW, $this->imageH);
// 设置背景
imagecolorallocate($this->_image, $this->bg[0], $this->bg[1], $this->bg[2]); // 验证码字体随机颜色
$this->_color = imagecolorallocate($this->_image, mt_rand(1,150), mt_rand(1,150), mt_rand(1,150));
// 验证码使用随机字体
$ttfPath = dirname(__FILE__) . '/Verify/' . ($this->useZh ? 'zhttfs' : 'ttfs') . '/'; if(empty($this->fontttf)){
$dir = dir($ttfPath);
$ttfs = array();
while (false !== ($file = $dir->read())) {
if($file[0] != '.' && substr($file, -4) == '.ttf') {
$ttfs[] = $file;
}
}
$dir->close();
$this->fontttf = $ttfs[array_rand($ttfs)];
}
$this->fontttf = $ttfPath . $this->fontttf; if($this->useImgBg) {
$this->_background();
} if ($this->useNoise) {
// 绘杂点
$this->_writeNoise();
}
if ($this->useCurve) {
// 绘干扰线
$this->_writeCurve();
} // 绘验证码
$code = array(); // 验证码
$codeNX = 0; // 验证码第N个字符的左边距
if($this->useZh){ // 中文验证码
for ($i = 0; $i<$this->length; $i++) {
$code[$i] = iconv_substr($this->zhSet,floor(mt_rand(0,mb_strlen($this->zhSet,'utf-8')-1)),1,'utf-8');
imagettftext($this->_image, $this->fontSize, mt_rand(-40, 40), $this->fontSize*($i+1)*1.5, $this->fontSize + mt_rand(10, 20), $this->_color, $this->fontttf, $code[$i]);
}
}else{
for ($i = 0; $i<$this->length; $i++) {
$code[$i] = $this->codeSet[mt_rand(0, strlen($this->codeSet)-1)];
$codeNX += mt_rand($this->fontSize*1.2, $this->fontSize*1.6);
imagettftext($this->_image, $this->fontSize, mt_rand(-40, 40), $codeNX, $this->fontSize*1.6, $this->_color, $this->fontttf, $code[$i]);
}
} // 保存验证码
$key = $this->authcode($this->seKey);
$code = $this->authcode(strtoupper(implode('', $code)));
$secode = array();
$secode['verify_code'] = $code; // 把校验码保存到session
$secode['verify_time'] = time(); // 验证码创建时间 $redis = $this->_redis();
$redis->set($key.$id,json_encode($secode)); header('Cache-Control: private, max-age=0, no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache'); ob_start();
imagepng($this->_image);
$image_data = ob_get_contents();
ob_end_clean(); //$base64 = base64_encode($imagedata); $image_data_base64 = 'data:image/png;base64,'.base64_encode ($image_data); return $image_data_base64; } /**
* 画一条由两条连在一起构成的随机正弦函数曲线作干扰线(你可以改成更帅的曲线函数)
*
* 高中的数学公式咋都忘了涅,写出来
* 正弦型函数解析式:y=Asin(ωx+φ)+b
* 各常数值对函数图像的影响:
* A:决定峰值(即纵向拉伸压缩的倍数)
* b:表示波形在Y轴的位置关系或纵向移动距离(上加下减)
* φ:决定波形与X轴位置关系或横向移动距离(左加右减)
* ω:决定周期(最小正周期T=2π/∣ω∣)
*
*/
private function _writeCurve() {
$px = $py = 0; // 曲线前部分
$A = mt_rand(1, $this->imageH/2); // 振幅
$b = mt_rand(-$this->imageH/4, $this->imageH/4); // Y轴方向偏移量
$f = mt_rand(-$this->imageH/4, $this->imageH/4); // X轴方向偏移量
$T = mt_rand($this->imageH, $this->imageW*2); // 周期
$w = (2* M_PI)/$T; $px1 = 0; // 曲线横坐标起始位置
$px2 = mt_rand($this->imageW/2, $this->imageW * 0.8); // 曲线横坐标结束位置 for ($px=$px1; $px<=$px2; $px = $px + 1) {
if ($w!=0) {
$py = $A * sin($w*$px + $f)+ $b + $this->imageH/2; // y = Asin(ωx+φ) + b
$i = (int) ($this->fontSize/5);
while ($i > 0) {
imagesetpixel($this->_image, $px + $i , $py + $i, $this->_color); // 这里(while)循环画像素点比imagettftext和imagestring用字体大小一次画出(不用这while循环)性能要好很多
$i--;
}
}
} // 曲线后部分
$A = mt_rand(1, $this->imageH/2); // 振幅
$f = mt_rand(-$this->imageH/4, $this->imageH/4); // X轴方向偏移量
$T = mt_rand($this->imageH, $this->imageW*2); // 周期
$w = (2* M_PI)/$T;
$b = $py - $A * sin($w*$px + $f) - $this->imageH/2;
$px1 = $px2;
$px2 = $this->imageW; for ($px=$px1; $px<=$px2; $px=$px+ 1) {
if ($w!=0) {
$py = $A * sin($w*$px + $f)+ $b + $this->imageH/2; // y = Asin(ωx+φ) + b
$i = (int) ($this->fontSize/5);
while ($i > 0) {
imagesetpixel($this->_image, $px + $i, $py + $i, $this->_color);
$i--;
}
}
}
} /**
* 画杂点
* 往图片上写不同颜色的字母或数字
*/
private function _writeNoise() {
$codeSet = '2345678abcdefhijkmnpqrstuvwxyz';
for($i = 0; $i < 10; $i++){
//杂点颜色
$noiseColor = imagecolorallocate($this->_image, mt_rand(150,225), mt_rand(150,225), mt_rand(150,225));
for($j = 0; $j < 5; $j++) {
// 绘杂点
imagestring($this->_image, 5, mt_rand(-10, $this->imageW), mt_rand(-10, $this->imageH), $codeSet[mt_rand(0, 29)], $noiseColor);
}
}
} /**
* 绘制背景图片
* 注:如果验证码输出图片比较大,将占用比较多的系统资源
*/
private function _background() {
$path = dirname(__FILE__).'/Verify/bgs/';
$dir = dir($path); $bgs = array();
while (false !== ($file = $dir->read())) {
if($file[0] != '.' && substr($file, -4) == '.jpg') {
$bgs[] = $path . $file;
}
}
$dir->close(); $gb = $bgs[array_rand($bgs)]; list($width, $height) = @getimagesize($gb);
// Resample
$bgImage = @imagecreatefromjpeg($gb);
@imagecopyresampled($this->_image, $bgImage, 0, 0, 0, 0, $this->imageW, $this->imageH, $width, $height);
@imagedestroy($bgImage);
} /* 加密验证码 */
private function authcode($str){
$key = substr(md5($this->seKey), 5, 8);
$str = substr(md5($str), 8, 10);
return md5($key . $str);
} }

调用生成图片验证码:

<?php
$codeId = 1; //可以根据不同使用场景传不同的ID
$infos = new Verify;
$base64Data = $infos->entry($codeId);
$returnData = [ 'imgSrc'=>$base64Data ];

 

校验验证码:

<?php

$verifyCode = new Verify;

if(!$verifyCode->check($confirmCode,$confirmCodeId))
{
echo '验证码错误';
}

  

RESTful API格式 图片验证码接口的更多相关文章

  1. day5(图片验证码接口)

    1.django缓存设置 django的六种缓存(mysql+redis) :https://www.cnblogs.com/xiaonq/p/7978402.html#i6 1.1安装Django缓 ...

  2. Django商城项目笔记No.4用户部分-注册接口-图片验证码

    Django商城项目笔记No.4用户部分-注册接口-图片验证码 1.首先分析注册业务接口 1.1.分析可得,至少这么几个接口 图片验证码 短信验证码 用户名是否存在 手机号是否存在 整体注册接口 图片 ...

  3. PHPer的项目RESTful API设计规范是怎样的?

    RESTful 是目前最流行的 API 设计规范,用于 Web 数据接口的设计. 什么是RESTful RESTful是一种软件设计风格, 主要用于客户端与服务端交互的软件. 一般来说RESTful ...

  4. 使用ASP.NET Core 3.x 构建 RESTful API - 3.1 资源命名

    之前讲了RESTful API的统一资源接口这个约束,里面提到了资源是通过URI来进行识别的,每个资源都有自己的URI.URI里还涉及到资源的名称,而针对资源的名称却没有一个标准来进行规范,但是业界还 ...

  5. Spring Boot学习笔记 - 整合Swagger2自动生成RESTful API文档

    1.添加Swagger2依赖 在pom.xml中加入Swagger2的依赖 <!--swagger2--> <dependency> <groupId>io.spr ...

  6. restful api上传文件(基础)-springboot

    基于restful api格式的文件上传(只是上传到本地): package com.nxz.controller; import com.nxz.entity.FileInfo; import or ...

  7. Python 实现简单图片验证码登录

    朋友说公司要在测试环境做接口测试,登录时需要传入正确的图片的验证码,本着懒省事的原则,推荐他把测试环境的图片验证码写死,我们公司也是这么做的^_^.劝说无果/(ㄒoㄒ)/~~,只能通过 OCR 技术来 ...

  8. jmeter通过cookie获取图片验证码实现登录2

    在登录时有一张图片验证码,需要获取验证码用于后续登录,见图 1.找到图片验证码接口写入jmeter 2.正则表达式提取cookie 3.Fiddler抓取登录成功的响应cookie,并设置成全局 4. ...

  9. Spring Boot 无侵入式 实现RESTful API接口统一JSON格式返回

    前言 现在我们做项目基本上中大型项目都是选择前后端分离,前后端分离已经成了一个趋势了,所以总这样·我们就要和前端约定统一的api 接口返回json 格式, 这样我们需要封装一个统一通用全局 模版api ...

随机推荐

  1. MySQL:日期函数、时间函数总结(MySQL 5.X)

    http://www.cnblogs.com/she27/archive/2009/01/16/1377089.html 原文:http://www.51sdj.com/phpcms/picture/ ...

  2. easyui-datebox 点击事件

    <div class="form-group col-xs-5 col-md-5 col-lg-6" style = "margin-left: 0px;" ...

  3. set_false_path的用法

    set_false_path的用法 非功能性路径,因为两个多路选择器被相同的选择信号驱动? 上电复位信号 set_false两个异步时钟域的路径 在两个时钟域之间,设置set_false_path,应 ...

  4. Pycharm初始创建项目和环境搭建

    Pycharm确实是一个非常不错的Python开发IDE,尤其对于初学者而言. 打开新建项目 1.选择新建一个Pure Python项目,新建项目路径可以在Location处选择. 2.Project ...

  5. SPI、I2C、UART、I2S、GPIO、SDIO、CAN 简介

    转自http://sanwen.net/a/fmxnjoo.html SPI.I2C.UART.I2S.GPIO.SDIO.CAN,看这篇就够了 总线 总线,总要陷进里面.这世界上的信号都一样,但是总 ...

  6. 403 Forbidden是什么意思?403 Forbidden错误解决方法

    大家平常在访问不同网站的时候,偶尔会遇到出现403 Forbidden错误的情况,浏览器会给出403 Forbidden错误提示.那么,403 forbidden是什么意思呢?出现403 Forbid ...

  7. java UCnter 单点登录 对接。

    前提 PHP项目要部署成功.论坛能正常访问. 先配置 应用 1.是论坛应用 4.是java服务器,也就是你java登录的项目. 必须通信成功. .主应用IP就是你java项目的入口. 例如:http: ...

  8. 怎样让scrollview滚动到底部?

    - (void)scrollsToBottomAnimated:(BOOL)animated { CGFloat offset = self.tableView.contentSize.height ...

  9. Redis 主从集群搭建及哨兵模式配置

    最近搭建了redis集群及哨兵模式,为方便以后查看特此记录下来: 1.Redis安装 2.主从架构 2.1 Redis主从架构图 2.2Redis主从结构搭建 Redis集群不用安装多个Redis,只 ...

  10. QTP 学习 - 检查点