让你的网站支持OTP、HOTP、TOTP两步验证功能

我们在网站上登录的账户的时候,一般都是填写账号和密码。但是有些网站的技术不给力,数据库被黑客拖库。而你刚好又是个不需要换密码的人,那么你其它网站的账户就很危险了,因为很有可能被人恶意登录。

所以作为网站的管理员,我们有必要为用户账户安全考虑,添加两步验证的功能。至于用户可以自行选择是否在登录的时候开启两步验证。

上面说了那么多,接下来我们看看两步验证具体的技术对接流程。

第一步,使用下面的php代码生成一个32位长度的随机字符

public function generateRandomClue($length = 32) {
      $b32 	= "234567QWERTYUIOPASDFGHJKLZXCVBNM";
      $s 	= "";
      for ($i = 0; $i < $length; $i++){
          $s .= $b32[rand(0,31)];
      }
     return $s;
}

拿到生成的secretkey

GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ

在微信上搜索二次验证器

https://static.ithome.io/upload/file/99493904-baf8-82d4-aa13-72ecb40fcd27/article_temp/20191024/b3139a299583243ea3f75cca7ef91be6.png

或者直接使用微信扫码

https://static.ithome.io/upload/file/99493904-baf8-82d4-aa13-72ecb40fcd27/article_temp/20191024/b6fae8e037caa8838a8ac8ce99064924.jpeg

创建一个手势密码,小程序将会使用这个手势密码来加密保存用户添加的key

用户根据使用不同的手势来区分多个场景,提高动态码的安全级别

https://static.ithome.io/upload/file/99493904-baf8-82d4-aa13-72ecb40fcd27/article_temp/20191024/386fa9834c36c11981a18b3706222460.png

进入到小程序页面后,然后点击底部的添加按钮

https://static.ithome.io/upload/file/99493904-baf8-82d4-aa13-72ecb40fcd27/article_temp/20191024/6ec706e12ef30d42ecbc96bab9f5167b.png

将我们使用php代码生成的secretkey 

GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ

添加到表单的key里面

https://static.ithome.io/upload/file/99493904-baf8-82d4-aa13-72ecb40fcd27/article_temp/20191024/8bb2d42b8563f99dd3060e17378d97e5.png

然后返回小程序页面我们就可以看到小程序每30秒生成一个新的

动态口令

每次用户需要登录系统的时候,都需要打开小程序查看这个动态口令

https://static.ithome.io/upload/file/99493904-baf8-82d4-aa13-72ecb40fcd27/article_temp/20191024/97415d2daaf746e524861edd55886381.png

接下来我们开始编辑登录页面的html代码

<!DOCTYPE html>
<html>
<head>
	<title>登录管理后台</title>
	<meta charset="utf-8">
	<style type="text/css">
		body{
			background: url(img/bg.jpg) 50% no-repeat fixed;
		    position: relative;
		    height: 100vh;
		    width:100vw;
		    background-size: cover;
		}
		.form-box{
			text-align: center;
			margin-top:300px;
		}
		.form-inner{
			background-color: white;
			display: inline-block;
			padding:30px;
			text-align: right;
			box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1)
		}
		.input-item,.button-item{
			margin-top:20px;
		}
		input{
			font-size:20px;
		}
		.button-item{
			margin-top:20px;
			text-align: center;
			font-size: 20px;
		}
	</style>
</head>
<body>
<div class="form-box">
	<form class="form-inner">
		<div class="input-item">
			账号:<input type="text" name="username">
		</div>
		<div class="input-item">
			密码:<input type="text" name="password">
		</div>
		<div class="input-item">
			动态码:<input type="text" name="code">
		</div>
		<div class="button-item">
			<input type="button" id="login-btn" value="登录">
		</div>
	</form>
</div>
<script type="text/javascript" src="js/jquery-3.4.1.min.js"></script>
<script type="text/javascript">
	$(document).ready(function(){
		$('#login-btn').click(function(e){
			const data = {
				username:$('input[name="username"]').val(),
				password:$('input[name="password"]').val(),
				code:$('input[name="code"]').val(),
			}
			$.post('./check.php',data).then((result)=>{
				console.info('hello',result)
				switch(result.code){
					case 'success':
						alert('登录成功');
					break;
					case 'error':
						alert(result.msg);
				}
			})
		})
	})
</script>
</body>
</html>

编辑check.php的登录验证码

<?php  
	header('Content-Type:applicaion/json');
	require_once(dirname(__FILE__).'/rfc6238/rfc6238.php');

	const username = 'admin';
	const password = 'admin123';

	// 这个32位的随机key是由系统提前生成。并告知用户,建议只给用户展示一次
	// 系统应保证每个用户的key都是唯一的
	const secretkey = 'GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ';

	if(!(isset($_POST['username']) && $_POST['username'] == username)){
		echo json_encode(['code' => 'error','msg' => '账号错误']);	
		return ;
	}

	if(!(isset($_POST['password']) && $_POST['password'] == password)){
		echo json_encode(['code' => 'error','msg' => '密码错误']);	
		return ;
	}

	if (TokenAuth6238::verify(secretkey,$_POST['code'])) {
		echo json_encode(['code' => 'success','msg' => '登录成功']);
		return ;
	} else {
		echo json_encode(['code' => 'error','msg' => '动态口令验证失败']);
		return ;	
	}

			
?>

然后我们尝试登录

https://static.ithome.io/upload/file/99493904-baf8-82d4-aa13-72ecb40fcd27/article_temp/20191024/4d62ba988ef22e7cd3812798f7ed788d.png

不错,我们现在已经完成了TOTP的协议,用户每次在登录的时候,都需要打开小程序获取动态码,这样就极大的保证了账户安全

最后完整的代码可以在开源中国上面找到

https://gitee.com/wuciyou/php-totp-demo

0条评论