之前公司写图片验证码时用的是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. LCA - Tarjan 算法

    void dfs(int u) { ; i <= n; i++) { if(visit[i]&&ask[u][i]) { LCA[u][i] = Find(i); } } vis ...

  2. Dynamics 365 CRM 添加自定义按钮

    在添加自定义按钮之前,我们需要下载这个工具 RibbonWorkbench, 它是专门针对自定义命令栏和Ribbon区域. 下载之后是一个zip压缩包. 怎样安装RibbonWorkbench: Se ...

  3. 第一章 HTML+CSS(中)

    4.域元素(form表单.textarea文本域.fieldset域集合.input使用) 案例 表单 用户名: 密码: 昵称: 你喜欢的水果有? 苹果 黄瓜 香蕉 请选择性别 男 女 请选择你要的网 ...

  4. py-day3-4 python 匿名函数

    # 匿名函数 lamdba name = 'xiaoma' f = lambda x:x+'jun' res = f(name) print('匿名函数的运行结果:',res) 匿名函数的运行结果: ...

  5. SVN 撤回已提交的代码

    1. TortoiseSVN -----> Show log 2.右键点击你想撤回的提交 -> Revert changes from this revision ----->Rev ...

  6. 依赖、耦合、解耦、控制反转(IOC)、依赖注入(DI)

    随着net的深入学习,出现了很多概念性的东西需要理解,现在统一记录一下. 1.依赖:现阶段在任何一个有请求作用的系统,都会出现A类调用B类的情况,这时候A类就依赖于B类,A类和B类存在依赖关系. 2. ...

  7. 初识rt-thread

    bernard.xiong CEO 熊谱祥 env,提供编译构建环境.图形化系统配置及软件包管理功能 scons 是 RT-Thread 使用的编译构建工具,可以使用 scons 相关命令来编译 RT ...

  8. TCP TIME_WAIT过多的解决方法

    总结: 最合适的解决方案是增加更多的四元组数目,比如,服务器监听端口,或服务器IP,让服务器能容纳足够多的TIME-WAIT状态连接.在我们常见的互联网架构中(NGINX反代跟NGINX,NGINX跟 ...

  9. kafka的log存储解析——topic的分区partition分段segment以及索引等(转发)

    原文 https://www.cnblogs.com/dorothychai/p/6181058.html 引言 Kafka中的Message是以topic为基本单位组织的,不同的topic之间是相互 ...

  10. 白话RPC

    RPC,这个英文缩写在计算机专业里的意思是:Remote Procedure Call Protocol,远程过程调用协议,字面上的意思就是这个,不过还是有些懵逼. 下面就简单说明一下其内在原理,形象 ...