详解thinkphp6后台添加google登录验证

news/2024/11/7 18:42:41/

把下面代码随意放到tp的项目里 注意下命名空间就可以

<?php//namespace app\authenticator;
//上面是你的命名空间class authenticator
{protected $_codeLength = 6;/*** Create new secret.* 16 characters, randomly chosen from the allowed base32 characters.** @param int $secretLength** @return string*/public function createSecret($secretLength = 16){$validChars = $this->_getBase32LookupTable();// Valid secret lengths are 80 to 640 bitsif ($secretLength < 16 || $secretLength > 128) {throw new Exception('Bad secret length');}$secret = '';$rnd = false;if (function_exists('random_bytes')) {$rnd = random_bytes($secretLength);} elseif (function_exists('mcrypt_create_iv')) {$rnd = mcrypt_create_iv($secretLength, MCRYPT_DEV_URANDOM);} elseif (function_exists('openssl_random_pseudo_bytes')) {$rnd = openssl_random_pseudo_bytes($secretLength, $cryptoStrong);if (!$cryptoStrong) {$rnd = false;}}if ($rnd !== false) {for ($i = 0; $i < $secretLength; ++$i) {$secret .= $validChars[ord($rnd[$i]) & 31];}} else {throw new Exception('No source of secure random');}return $secret;}/*** Calculate the code, with given secret and point in time.** @param string $secret* @param int|null $timeSlice** @return string*/public function getCode($secret, $timeSlice = null){if ($timeSlice === null) {$timeSlice = floor(time() / 30);}$secretkey = $this->_base32Decode($secret);// Pack time into binary string$time = chr(0) . chr(0) . chr(0) . chr(0) . pack('N*', $timeSlice);// Hash it with users secret key$hm = hash_hmac('SHA1', $time, $secretkey, true);// Use last nipple of result as index/offset$offset = ord(substr($hm, -1)) & 0x0F;// grab 4 bytes of the result$hashpart = substr($hm, $offset, 4);// Unpak binary value$value = unpack('N', $hashpart);$value = $value[1];// Only 32 bits$value = $value & 0x7FFFFFFF;$modulo = pow(10, $this->_codeLength);return str_pad($value % $modulo, $this->_codeLength, '0', STR_PAD_LEFT);}/*** Get QR-Code URL for image, from google charts.** @param string $name* @param string $secret* @param string $title* @param array $params** @return string*/public function getQRCodeGoogleUrl($name, $secret, $title = null, $params = array()){$width = !empty($params['width']) && (int)$params['width'] > 0 ? (int)$params['width'] : 200;$height = !empty($params['height']) && (int)$params['height'] > 0 ? (int)$params['height'] : 200;$level = !empty($params['level']) && array_search($params['level'], array('L', 'M', 'Q', 'H')) !== false ? $params['level'] : 'M';$urlencoded = urlencode('otpauth://totp/' . $name . '?secret=' . $secret . '');if (isset($title)) {$urlencoded .= urlencode('&issuer=' . urlencode($title));}return "https://api.qrserver.com/v1/create-qr-code/?data=$urlencoded&size=${width}x${height}&ecc=$level";}/*** Check if the code is correct. This will accept codes starting from $discrepancy*30sec ago to $discrepancy*30sec from now.** @param string $secret* @param string $code* @param int $discrepancy This is the allowed time drift in 30 second units (8 means 4 minutes before or after)* @param int|null $currentTimeSlice time slice if we want use other that time()** @return bool*/public function verifyCode($secret, $code, $discrepancy = 1, $currentTimeSlice = null){if ($currentTimeSlice === null) {$currentTimeSlice = floor(time() / 30);}if (strlen($code) != 6) {return false;}for ($i = -$discrepancy; $i <= $discrepancy; ++$i) {$calculatedCode = $this->getCode($secret, $currentTimeSlice + $i);if ($this->timingSafeEquals($calculatedCode, $code)) {return true;}}return false;}/*** Set the code length, should be >=6.** @param int $length** @return PHPGangsta_GoogleAuthenticator*/public function setCodeLength($length){$this->_codeLength = $length;return $this;}/*** Helper class to decode base32.** @param $secret** @return bool|string*/protected function _base32Decode($secret){if (empty($secret)) {return '';}$base32chars = $this->_getBase32LookupTable();$base32charsFlipped = array_flip($base32chars);$paddingCharCount = substr_count($secret, $base32chars[32]);$allowedValues = array(6, 4, 3, 1, 0);if (!in_array($paddingCharCount, $allowedValues)) {return false;}for ($i = 0; $i < 4; ++$i) {if ($paddingCharCount == $allowedValues[$i] &&substr($secret, -($allowedValues[$i])) != str_repeat($base32chars[32], $allowedValues[$i])) {return false;}}$secret = str_replace('=', '', $secret);$secret = str_split($secret);$binaryString = '';for ($i = 0; $i < count($secret); $i = $i + 8) {$x = '';if (!in_array($secret[$i], $base32chars)) {return false;}for ($j = 0; $j < 8; ++$j) {$x .= str_pad(base_convert(@$base32charsFlipped[@$secret[$i + $j]], 10, 2), 5, '0', STR_PAD_LEFT);}$eightBits = str_split($x, 8);for ($z = 0; $z < count($eightBits); ++$z) {$binaryString .= (($y = chr(base_convert($eightBits[$z], 2, 10))) || ord($y) == 48) ? $y : '';}}return $binaryString;}/*** Get array with all 32 characters for decoding from/encoding to base32.** @return array*/protected function _getBase32LookupTable(){return array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', //  7'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 15'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 23'Y', 'Z', '2', '3', '4', '5', '6', '7', // 31'=',  // padding char);}/*** A timing safe equals comparison* more info here: http://blog.ircmaxell.com/2014/11/its-all-about-time.html.** @param string $safeString The internal (safe) value to be checked* @param string $userString The user submitted (unsafe) value** @return bool True if the two strings are identical*/private function timingSafeEquals($safeString, $userString){if (function_exists('hash_equals')) {return hash_equals($safeString, $userString);}$safeLen = strlen($safeString);$userLen = strlen($userString);if ($userLen != $safeLen) {return false;}$result = 0;for ($i = 0; $i < $userLen; ++$i) {$result |= (ord($safeString[$i]) ^ ord($userString[$i]));}// They are only identical strings if $result is exactly 0...return $result === 0;}
}

在控制器里引入类直接调用

        $authenticator = new authenticator();$secret = $autheticator->createSecret();//这里的secret 是要写进数据库 验证的时候用的$username = "123456";//随便写个用户名测试 $qrCodeUrl = $authenticator->getQRCodeGoogleUrl($username, $secret);//这里就直接生成二维码//如果不想第三方生成的话也可以自己生成,格式例如:otpauth://totp/123456?secret=ZKKCM47ECZTUQ77S$secret = "ZKKCM47ECZTUQ77S";//这里的secret是类模块createSecret()方法生成的$code="737045";//这里的数字就是绑定后生成的动态令牌$checkResult = $authenticator->verifyCode($secret, $code, 4);//验证code的合法性if (!$checkResult) {echo('谷歌验证码错误');die();}

插件安装地址 https://authenticator.cc/


http://www.ppmy.cn/news/547687.html

相关文章

Tensorflow实战(六)Googe inception Net和ResNet

实验&#xff08;一&#xff09;Google inception Net 第一个inception 1.基本模型块 2.第一个inception 第二个inception 1.基本模型块 2. 第二个inception inception v4

googe isg理解

如何生成汇编指令流 增加directed stream 主要指令流 insert_jump_instr ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 栈的长度 这里注意一下&#xff0c;栈的长度&#xff0c;是每一次都会随机在这个范围&#xff0c;所以每一次都会减去随机生成的栈的长度&#xff0c;留…

googe分析里面创建的转化目标,谷歌后台找不到怎么回事?

Google analysis后台&#xff1a; Google adwords 后台&#xff1a; 我们会发现是空的&#xff0c;为什么呢。怎么刷新都找不到。每当遇到这种问题&#xff0c;小伙伴们&#xff0c;不要着急&#xff0c;这是个常见问题&#xff0c;我们现在能做的只有等。是系统延迟。只要我们…

谷歌浏览器设置中文教程

谷歌浏览器是由谷歌公司推出的一款网页浏览器&#xff0c;稳定性强&#xff0c;运行速度快&#xff0c;唯一不足的应该就是它不是中文的&#xff0c;那要如何给谷歌浏览器设置中文&#xff1f;下面就一起来看看具体的设置方法吧。 谷歌浏览器怎么设置中文&#xff1f; 1、进入浏…

谷歌在中国大陆停止谷歌翻译服务,Chrome “翻成中文”无法使用

我们一般可能很少用到“translate.google.cn”这种机翻网站。在一些出海行业可能会经常用到谷歌翻译&#xff0c;毕竟机翻各种语言谷歌翻译要稍微出彩一些。山外有山&#xff0c;谷歌的业务遍布全球各地&#xff0c;相对在多国语言的资源也比较成熟。上次谷歌停止谷歌地图在中国…

linux如何卸载谷歌输入法,Linux上使用谷歌输入法

Linux下使用谷歌输入法 Linux的中文输入法一直太烂&#xff0c;scim终于出来对googlePinyin的支持了。 安装步骤&#xff1a; 1、安装scim: sudo apt-get install scim 2、从git上checkout下来scim-googlepinyin的源代码&#xff1a; 如果没有安装git&#xff0c;那么可以使用&…

Google earth engine 入门与简介

Google Earth Engine是Google提供的对大量全球尺度地球科学资料&#xff08;尤其是卫星数据&#xff09;进行在线可视化计算和分析处理的云平台。该平台能够存取卫星图像和其他地球观测数据数据库中的资料并足够的运算能力对这些数据进行处理。 通俗的来讲&#xff0c;就是Goo…

[2012年4月30日] 解决火狐浏览器 Firefox 12.0 地址栏搜索引擎自动跳转到googe.com.hk的问题

最近从谷歌浏览器 Chrome 转移到了火狐浏览器 Firefox 12.0; 本文主要解决使用地址栏搜索时总是跳转到google.com.hk的问题: 此方法解决Firefox浏览器 跳转到google.com.hk的问题: 1. 在地址栏输入about:config 2. 输入keyword, 在结果中找到keyword.URL 3. 把值修改成 h…