Ethers.js 签名认证

Ethers.js
通用
DAPP

核心:通过后端获取随机数,拿到随机数后进行签名,再次请求后端验证随机数是否一致,一致则代表签名正确。

const main = async () => {
	const provider = new ethers.BrowserProvider(window.ethereum);
	await window.ethereum.request({
		method: "eth_requestAccounts",
	});
	const signer = await provider.getSigner();
	const address = signer.address;

	const nonce = auth(state.address);
	const signature = await signer.signMessage(nonce.toString());
	const signStatus = verify(state.address, signature);
	console.log(signStatus);
};

// 服务端方法模拟
const auth = (address) => {
	let user = users[address];
	if (!user) {
		user = {
			address,
			nonce: Math.floor(Math.random() * 10000000),
		};
		users[address] = user;
	} else {
		const nonce = Math.floor(Math.random() * 10000000);
		user.nonce = nonce;
		users[address] = user;
	}
	return user.nonce;
};

const verify = (address, signature) => {
	let signValid = false;
	console.log(`address: ${address}`);
	//从数据库中取出nonce
	let nonce = users[address].nonce;
	//验证对nonce进行签名的地址
	const decodedAddress = ethers.verifyMessage(
		nonce.toString(),
		signature.toString()
	);
	//比较地址和签名的地址是否一致
	if (address.toLowerCase() === decodedAddress.toLowerCase()) {
		signValid = true;
		//出于安全原因,更改nonce,防止下次直接使用相同的nonce进行登录
		users[address].nonce = Math.floor(Math.random() * 10000000);
	}
	return signValid;
};