零、前言
这个项目的灵感,其实最初是在了解Yubikey时得来的。
但是看了下Yubikey的价格,虽说并不是完全买不起,但也并非白菜价。
最近研究网页内NFC多一些,于是灵光一现,就有了这样一个项目。
需要说明的是,目前项目仓库中的模板仅对卡号进行了获取、传参和验证的步骤。在用于生产环境时,还应校验卡中的其他信息;或者,将卡号作为两步验证的选项之一,也是个不错的选择。
一、前端读取NFC标签
这部分网上的教程相对较多,但也比较杂,有很多过时或是已经不兼容的。
经过测试、调整和删减,下面的代码可以在前端正常读取NFC标签。
<button id="readNFC">Read NFC Tag</button>
<p id="output"></p>
<script>
async function readNFC() {
try {
if ('NDEFReader' in window) {
document.getElementById("readNFC").style.display="none";
var x = document.getElementById("output");
x.innerHTML = "Touch your Card now";
const reader = new NDEFReader();
reader.scan().then(() => {
reader.addEventListener("reading", ({ message, serialNumber }) => {
alert(`> Serial Number: ${serialNumber}`);
});
}).catch(error => {
alert("Error reading NFC: " + error);
});
} else {
alert("[Web NFC]Browser not supported");
}
} catch (error) {
console.error("Error reading NFC: ", error);
}
}
document.getElementById('readNFC').addEventListener('click', readNFC);
</script>
根据目前的测试,上述代码在Microsoft Edge、Google Chrome、Bromite Chromium、Kiwi Browser等手机端浏览器中都可以正常读取NFC标签。
有一些浏览器会显示“不支持”;而另一些会直接显示“权限被拒绝”,经测试这些提示被拒绝的多为基于Chromium进行二次开发的,可能是在二开代码过程中对于已有NFC模块直接进行了拒绝处理。目前现行手机大部分硬件上都具有NFC标签,因此如果提示不支持或被拒绝,一般更换软件(浏览器)即可。
二、将卡号传回后端进行验证
第一部分中,我们已经实现了通过NFC读取卡号,并通过alert方式将其在前端显示。
下面,我们通过修改"reading"所对应的事件来将其传回后端。
首先,写一个用于提交数据的表单,并添加一个隐藏(hidden)的字段用于存放卡号:
<form id="nfcForm" method="post" action="check.php">
<div class="input-box">
<input type="hidden" name=card id="CardID" />
</div>
</form>
然后修改其事件来实现在成功读取卡号后触发提交:
document.getElementById('CardID').value = serialNumber; document.getElementById('nfcForm').submit();
check.php获得所传递的卡号:
$card=$_POST['card'];
(完整代码见GitHub仓库)
这里我们使用的是Post方式。此外,在一些不方便使用Post传参的场景下,我们其实也可以利用cookie临时储存等其他方式来传递这个参数。
三、写在最后
目前,这个模板是通过Session进行登录的。
实际上,我们还可以通过SAML协议来进行统一认证和登录,从而进一步提高其易用性。
SAML是一种开源的综合登录方法,其可移植性更强,普及性也更加广泛。
对于SAML的实现方法,留待下次更新。🙂
- 【原创】转载请注明出处
文章评论