QRコード作成ツールを作る

掲載日

はじめに

前回GolangでQRコードを作るライブラリを試したので、今度はオンラインでQRコードを作成できるツールを作成します。

QRコード作成用APIを作成する(Golang)

まずはQRコードを作成するためのAPIを作成します。
機能として、QRの中央にロゴ画像を配置したりハーフトーン画像を設定できるようにしたいので、
画像のアップロードAPIとQRコード作成のAPIの二つを作成します。

画像のアップロードAPI

完成したコードがこちら。

利用者側からのアップロードということで、以下の攻撃の対策をしてあります。
(個人サイトなので、標的にはなりにくいでしょうが勉強のため…。)

  • アップロードされたファイルをルートディレクトリ上に置かない・置けないように。
    いわゆるディレクトリトラバーサル対策。
    ルート上に実行可能なPHPファイル等をアップロードさせることで、そのファイルをURL叩いて実行してあれこれする攻撃です。
    ルート上に置かないのはもちろんですが、それを見越して攻撃側がファイル名を「../」のようにして来るパターンもあるので「アップロードされたファイルはサーバー側で一意な名前を付けて、ルート外に保存する」ことで対策をします。
  • ファイルのタイプチェック
    画像以外のファイル(exe等)を拡張子などを偽ってアップロードする攻撃も対策してます。
    今回はQRコードに埋め込むための画像アップロード処理で、ユーザーや管理者側でそのファイルを実行するタイミングはないですが、今後別のツールに流用しないとも限らないので念のため。
    拡張子やMIMEタイプチェックの方法はこちらのサイトを参考にさせて頂きました。

QRコード作成API

完成したコードがこちら。

やってることはリクエストを基に前回の記事で書いたオプションを追加したり追加しなかったりするだけです。

ただ、リクエストを受けるにあたって、フロント側でinputタグのcolorタイプを使用しています。
このタグはブラウザの機能でカラーピッカーを表示して色コードを取得できる優れものなのですが、
取得できるのは、CSSなどでおなじみの「#ffffff」形式、つまり

16 進表記で RGB カラーを特定する 7 文字

mdnより引用

となります。(恥ずかしながらこの形式が16進数であること、#RRGGBB(R: Red, G: Green, B:Blueで、2桁の16進数なので各色 0 ~ 255を示せる)を今回初めて知りました。)

オプションで前景色、背景色は16進数の表記でもいけるのですが、グラデーションのみ以下の形式で色を追加していく必要があります。

rgba := color.RGBA{0, 0, 0, 255}

そのため、カラーコードを16進数から10進数にコンバートしてあげる必要があるため、以下の処理を挟んでいます。

// #rrggbb(16進数)を分解してRGBAに変換する
func convertHexToRGB(hex string) (color.RGBA, error) {
	rgba := color.RGBA{0, 0, 0, 255}
	switch len(hex) {
	case 7:
		_, err := fmt.Sscanf(hex, "#%02x%02x%02x", &rgba.R, &rgba.G, &rgba.B)
		if err != nil {
			return rgba, err
		}
		break
	case 4:
		_, err := fmt.Sscanf(hex, "#%1x%1x%1x", &rgba.R, &rgba.G, &rgba.B)
		if err != nil {
			return rgba, err
		}
		rgba.R *= 17
		rgba.G *= 17
		rgba.B *= 17
		break
	}
	return rgba, nil
}

画面を作成する。(Nuxt)

続いてQRコードを作成する条件を入力するための画面を作成します。
完成したコードがこちら。

画面側ではそんなに複雑なことはしてないですが、一個地味に詰まったのが、グラデーションを付けるときにカラーピッカーを複数入力できるようにしたかったので「入力欄を増やす時ってどうするの?」という所。
javascriptやjQueyだと「既存の要素をcloneしてappend」もしくは「createElementしてappend」すればいいですが、Nuxtでも(前述の方法でも出来るけど)あまりスマートではないよなと。

調べて見つけたのがこちらの記事。
Nuxtなら配列でv-forで要素を表示しておいて、その配列を増やせば入力欄を増やせます。
いわれてみれば確かにという感じなんですが、javascriptやjQuery的な作り方に慣れてしまって中々Nuxtっぽい解決策が思いつかず。

参考サイト

記事の作成者のA.W.のアイコン

この記事を書いた人

A.W.
茨城県在住Webエンジニアです。 PHPなどを業務で使用しています。 趣味ではGoやNuxt、Flutterをやってます。

Comment