🔑

TOTP認証をデスクトップ画面で簡単管理するアプリをGo言語で作ってみた

2024/09/29に公開

はじめに

本記事では、Go言語を使ってTOTP (Time-based One-Time Password) コードを生成し、システムトレイに表示するアプリケーションを紹介します。この記事で取り上げるアプリケーションは、簡単なユーザーインターフェースを持ち、トークンを更新し、ワンクリックでクリップボードにコピーできる機能を持っています。

このアプリを利用することで、2段階認証の際に毎回authenticatorアプリを開く手間を省くことができます。

前提条件

  • Go 1.23+
  • github.com/pquerna/otp/totp パッケージ
  • github.com/atotto/clipboard パッケージ
  • github.com/getlantern/systray パッケージ
  • アイコンファイル (例: icon.ico)

プログラム概要

このアプリケーションでは、環境変数に保存されたTOTPキーを使用して、システムトレイ上でTOTPコードを表示し、ユーザーがクリップボードにコピーできます。

主な機能は以下の通りです。

  • TOTPキーの生成と表示
  • トークンのクリップボードへのコピー
  • 定期的なトークンの更新
  • アプリケーションの終了機能

コードの説明

メイン処理

func main() {
    systray.Run(onReady, onExit)
}

systray.Run()を使用して、システムトレイのメニューを表示し、onReady()関数で初期化を行います。onExit()はアプリケーション終了時に実行される関数です。

TOTPコードの生成と更新

go func() {
    ticker := time.NewTicker(1 * time.Second)
    defer ticker.Stop()
    for range ticker.C {
        code, err := totp.GenerateCode(secret, time.Now())
        if err != nil {
            fmt.Println("Error generating TOTP code: ", err)
            continue
        }
        systray.SetTooltip(code)
    }
}()

この部分は1秒ごとにTOTPコードを生成し、トレイアイコンのツールチップに表示します。TOTPコードは時刻に依存しているため、一定の時間間隔で更新されます。

クリップボードへのコピー

go func() {
    for range copyMenuItem.ClickedCh {
        otp, err := totp.GenerateCode(secret, time.Now())
        if err != nil {
            fmt.Println("Error generating TOTP code: ", err)
            continue
        }
        err = clipboard.WriteAll(otp)
        if err != nil {
            fmt.Println("Error copying TOTP code to clipboard: ", err)
        } else {
            fmt.Println("Copied TOTP code to clipboard")
        }
    }
}()

ユーザーが「Copy」メニューをクリックすると、現在のTOTPコードが生成され、クリップボードにコピーされます。

アイコンの読み込み

func icoToByteArray(path string) []byte {
    file, err := os.Open(path)
    if err != nil {
        return nil
    }
    defer file.Close()

    byteArray, err := io.ReadAll(file)
    if err != nil {
        return nil
    }

    return byteArray
}

この関数では、指定されたファイルパスからアイコンファイルを読み込み、バイト配列として返します。これにより、システムトレイにカスタムアイコンを設定できます。

実行方法

  1. 必要な依存ライブラリをインストールします。
  2. TOTPキーとアイコンのパスを環境変数に設定します。
    export TOTP_SECRET="YOUR_SECRET_TOTP_KEY"
    export TOTP_ICON_PATH="/path/to/icon.ico"
    
  3. アプリケーションを実行します。
    go run main.go
    
    これで、システムトレイにTOTPアイコンが表示され、ツールチップとしてワンタイムパスワードが定期的に更新されます。Copyメニューをクリックすることで、パスワードをクリップボードにコピーできます。

詳細は下記リポジトリのREADMEを参照してください。
https://github.com/dqx0/desktop-totp

Discussion