Kaikas로그인 정보를 백엔드로 넘기는 방법이 있나요?

현재 NodeJS 환경에서 caver-js를 이용해 민팅 사이트를 만들고있는데 프론트에서 카이카스를 이용해 유저인증을하고 컨트랙트와 통신하는 방법을 알지만 보안상의 이유로 백엔드에서 이러한 것을 처리하고싶은데 백엔드에서 caver-js를 사용할 경우 무조건 유저키가 필요한것으로 나오는데 이에대해 질문이 있습니다.

  1. 카이카스로 로그인한 정보를 그대로 백엔드로 넘기는 방법은 없나요?
    아래 구문은 _address로 유저의 주소를 받았습니다. addWhiteList 부분은 작동하지만 .send() 안쪽 from: _address 부분은 Error: Returned error: unknown account 뜨고 작동하지않습니다
    await contract.methods
    .addWhiteList(_address)
    .send({
    from: _address,
    gas: “200000”,
    })
    .then(function (result) {
    console.log(result);
    })

    .catch(function (error) {

    console.log(error);

    });

  2. 백엔드에서 유저에게 서명을 요구하고 컨트랙트에 트랜잭션을 보내는 것은 좋은 처리방법이 아닌가요?

안녕하세요

Caver를 이용해 클라이언트에서 SignedMessage 를 만들고 서버에서 보내 서버에서 검증하시면 됩니다.

아래 간단한 예제 추가했습니다.


Client

import Caver from 'caver-js';

async function bootstrap() {
  const caver = new Caver((window as any).klaytn);
  const [address] = await (window as any).klaytn.enable();
  const signedMessage = await caver.rpc.klay.sign(address, 'my message');

  const payload = await fetch('http://localhost:3001/verify', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      address,
      signedMessage,
    }),
  });

  console.log(await payload.json());

}

bootstrap();

Server

import Caver from 'caver-js';
import express from 'express';
import cors from 'cors';
import bodyParser from 'body-parser';

const caver = new Caver('https://public-node-api.klaytnapi.com/v1/baobab');

async function validateSignedMessage(message: string, signedMessage: string, address: string) {
  const v = '0x' + signedMessage.substring(2).substring(128, 130);
  const r = '0x' + signedMessage.substring(2).substring(0, 64);
  const s = '0x' + signedMessage.substring(2).substring(64, 128);
  return await caver.validator.validateSignedMessage(
    message,
    [v, r, s],
    address,
    false,
  );
}

const app = express();

app.use(cors());
app.use(bodyParser());

app.post('/verify', async (req, res) => {
  const { address, signedMessage } = req.body;

  const isValid = await validateSignedMessage('my message', signedMessage, address);

  res.json({
    isValid,
  });
});

app.listen(3001, () => {
  console.log('Example app listening on port 3001');
});
2개의 좋아요

위와 같이 작성했는데 결과값으로 계속해서 false가 나옵니다.

안녕하세요

서버, 클라이언트 코드, 의존성 버전도 함께 공유해주시면

자세하게 답변 드리도록 하겠습니다.

2개의 좋아요


다음과 같은 방식으로 프론트에서 signature와 지갑 address를 백엔드로 보내면

const isValid = await caver.validator.validateSignedMessage(
        hash,
        caver.utils.decodeSignature(signature),
        address,
        false,
      );

위와 같은 방식으로 검증을 진행하고 있는데 올바른 값을 보내도 계속 false만 나오네요…

의존성 버전은 ^1.8.1 사용하고 있습니다.

아래와같이 클라이언트에서 바로 validate하여 정상적으로 작동하는것을 확인했습니다.

async function bootstrap() {
  const caver = new Caver((window as any).klaytn);
  const [address] = await (window as any).klaytn.enable();

  const signedMessage = await caver.rpc.klay.sign(address, 'my message');
  const isValid = await caver.validator.validateSignedMessage('my message', caver.utils.decodeSignature(signedMessage), address);

  console.log(isValid);
}

bootstrap();

혹시 sign 하는 메시지에 한국어를 지원하지 않나요? 혹시 몰라서 한국어로 썻던 메시지를 Welcome! 으로 고치니까 바로 작동하네요… 이 부분은 문제가 있다고 생각합니다.