LoginSignup
8
6

More than 3 years have passed since last update.

Mpurseの署名機能を使って、ユーザID、パスワード、クレカ不要の認証機能の実装

Last updated at Posted at 2019-07-17

はじめに

こんちわ、らいうです!

Ask mona 3.0のようなログイン機能を実装したいと思い、数日格闘していました。
今日、なんとかサンプルプロジェクトができたので、メモを残しておきます。

ソースに関してはこちら
https://github.com/Raiu1210/mpurse_login

環境

・Mac OS Mojave
・node -v -> v10.16.0
・vue -V -> 3.9.2
・python 2.7.10

node.jsに関してはもうやってる人も多いと思いますがnvmを使って、プロジェクトごとにバージョンを切り替えられるようにしておきましょう。
また、bitcoreやbitcoin-jsなどのモジュールをnpm installする際にpython2.系が必要になるっぽいです。

僕は、Macのセットアップでデフォのpython2.7をアンインストールしてpyenvでpython3系を使っていたので、エラーが出ました。
pyenvでlocalを2.7.10を指定しました。

やったことの流れ

プロジェクトの土台に関しては
https://qiita.com/y4u0t2a1r0/items/a6aea444efc8e8e65293
この記事を参考にしながら作っていきました。
この記事でローカル環境において
・node.jsで構築したバックエンドとVue.jsで作ったフロントがPOST通信できるようにします。

上の記事で作ったフロント側を、前に僕が書いた記事で作ったものに置き換えてhttps対応などすることで
window.mpurseインスタンスが使える(インジェクトされる)ようにします。
https://qiita.com/Raiu1210/items/b4031624e3829c8bd672

バックエンドもhttps化するために
https://kaworu.jpn.org/javascript/node.js%E3%81%AB%E3%82%88%E3%82%8BHTTPS%E3%82%B5%E3%83%BC%E3%83%90%E3%81%AE%E4%BD%9C%E3%82%8A%E6%96%B9
この記事を参考にしました。
上でリンクを張った僕の記事で、opensslを使ってオレオレ証明書をそろえますが、同じ証明書に対してパスを通せばOKでした。

フロントエンド

処理のイメージとしては
・フロントでメッセージにmpurseで署名をする
・バックエンドにPOSTする
 内容
  ・メッセージ
  ・アドレス
  ・署名
・署名結果を待つ、受け取る
といった形です。

index.js
import axios from 'axios'

export default () => {
  return axios.create({
    baseURL: 'https://localhost:3000/'
  })
}

これは、参考にして作ったものとほとんど変わらないですね

これが署名を作ってPOSTする関数です。
HelloWorld.vueで作ったボタンを押した際に呼ばれます

method.js
import Api from './index'

export default {
  async ask_verify_sig () {
    var date = new Date();
    var a = date.getTime();

    var address = await window.mpurse.getAddress()
    var message = "Please sign this message :" + a
    var signature = await window.mpurse.signMessage(message);

    const item = { address: address, message: message, signature: signature }
    return Api().post('/verify', item)
  }
}

現在のタイムスタンプを取得して、署名メッセージを作成します。
そして、それを引数としてmpurseのsignMessage()に渡します。

その後、itemにAddress, message, signatureを入れてPOSTします。

trueが返ってきた場合とfalseが返ってきた場合で適当なメッセージを決めて,alertするようにしました。
これで目に見えてデカデカと確認できます。

バックエンド

バックエンドではbitcoinjs-messageを使って、署名を検証しました。
python3系を使っている人は注意。pyenvなどでこのディレクトリ内では2系にしましょう。

それを確認したら

npm install bitcoinjs-message

しましょう。

index.js
const express = require('express')
const bodyParser = require('body-parser')
const bitcoinMessage = require('bitcoinjs-message')
const cors = require('cors')
const app = express()

const messagePrefix = "\x19Monacoin Signed Message:\n"

var fs = require('fs');
var https = require('https');
app.use(bodyParser.json())
app.use(cors())

var options = {
  key:  fs.readFileSync('../../../work/ssl/localhost.key'),
  cert: fs.readFileSync('../../../work/ssl/localhost.crt')
};

var server = https.createServer(options,app);

app.post('/verify', function(req, res) {
  var date = new Date();
  var a = date.getTime();
  var address = req.body.address
  var message = req.body.message
  var signature = req.body.signature

  var result = message.split(':');
  var time_diff = a - parseInt(result[1], 10)

  var is_varify = bitcoinMessage.verify(message, address, signature, messagePrefix)
  console.log(is_varify)

  if(time_diff < 6000 && is_varify) {
    var return_message = true
  } else {
    var return_message = false
  }

  res.send({
    message: return_message
  })
})

server.listen(3000);

まず

const bitcoinMessage = require('bitcoinjs-message')

で、bitcoinjs-messageをインポートしてきます。
そして大事なのが

const messagePrefix = "\x19Monacoin Signed Message:\n"

これのおかげでモナコインに対応してくれます。

ここに関しては
海野('A`)ヴァー山猿:https://twitter.com/CryptoMonkey_ja
さんが教えてくれました!
ありがとうございます!

bitcoin-js-messageとbitcore-messageでの検証の仕方を教えてくれました
https://gist.github.com/fkfk/7652bb480197036c31bac186f697bd65

そして検証に関して、一応
署名が直近1分以内に行われた場合にtrueを返すようにしてみました。
ただ、https通信でないとmpurseは使えないので、正直この機能はいらないかもしれません。

future work

今日、脇Pからアドバイスもらって
https://github.com/cryptocoinjs/coininfo

こんなものがあるそうです。
Monacoinに限らずAltcoinを扱う場合にとても便利そうでした。
次はこれ使ってみようと思っているので、またその時は記事書きます。

 ざっくりこんなかんじ

とまあ、さっくり書いてみました。
十分な説明でなかったらコメントやtwitterでDMしてください。
twitter : https://twitter.com/Mr_1484

8
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6