Tauri(Rust) × AI で作る GitGUIクライアントアプリ その4
2025.04.10
どもです。
熱は治まり体調も徐々に回復してきました。
今回は前回の「Tauri(Rust) × AI で作る GitGUIクライアントアプリ その3」の続きとなり、Rust側の処理も追加していこうと思います。
まずは、ログインフォームより、UsernameとPasswordを取得し、keyring-rsクレートを用いてそれらをキーチェーンに登録していきます。
今回も極力コーディングせずノーコードで、
そのままの思いをCursorに。
ログイン情報登録
「Rust側の処理を作っていこうかな。
まずはフォームより、UsernameとPasswordを受取り
keyring-rs クレートを用いてキーチェーンに登録する処理が欲しい」
はい、Rust側でキーチェーンに認証情報を保存する処理を実装しましょう。 まず、必要なクレートを追加します:
それからCursorさんがあぁだこうだ言った後、
keyring = "2.3.2"
keyringクレートが追加されますが、ChatGPTの時もそうなのですが、最新バージョンは3.6.2なのですが、バージョン2.3.2を使いたがります。
一旦、そのまま進めるとし、
use serde::{Deserialize, Serialize}; use keyring::Entry; #[derive(Debug, Serialize, Deserialize)] struct Credentials { username: String, password: String, } #[tauri::command] fn save_credentials(credentials: Credentials) -> Result<(), String> { let entry = Entry::new("branchie", &credentials.username) .map_err(|e| e.to_string())?; entry.set_password(&credentials.password) .map_err(|e| e.to_string())?; Ok(()) } #[tauri::command] fn get_credentials(username: String) -> Result<String, String> { let entry = Entry::new("branchie", &username) .map_err(|e| e.to_string())?; entry.get_password() .map_err(|e| e.to_string()) }
と、処理が追加されます。
tauri::Builder::default() .invoke_handler(tauri::generate_handler![save_credentials, get_credentials]) .run(tauri::generate_context!()) .expect("error while running tauri application");
invoke handlerにもそれらの関数が追加されます。
これで、以下の機能が実装されました: 1.save_credentialsコマンド: ・ユーザー名とパスワードを受け取り、システムのキーチェーンに保存 ・サービス名は"branchie"として登録 ・エラーが発生した場合はエラーメッセージを返す 2.get_credentialsコマンド: ・ユーザー名を指定して、保存されたパスワードを取得 ・エラーが発生した場合はエラーメッセージを返す フロントエンド側からは以下のように使用できます:
// 認証情報の保存 await invoke('save_credentials', { credentials: { username: 'ユーザー名', password: 'パスワード' } }); // 認証情報の取得 const password = await invoke('get_credentials', { username: 'ユーザー名' });
この実装により、セキュアな方法で認証情報を管理できます。キーチェーンはOSのセキュリティ機能を利用して、認証情報を安全に保存します。 次のステップとして、フロントエンドのLogin.vueコンポーネントを更新して、これらのコマンドを使用するように修正しましょうか?
そうですね。
Login.vueコンポーネントも修正していきましょうー。
では、Login.vueを編集して、Rust側のコマンドを使用するように実装しましょう:
import { invoke } from "@tauri-apps/api/tauri";と
と。ここで一つ間違いを出す。
import { invoke } from “@tauri-apps/api/core”;なので間違いを指摘。
これで、必要な実装が完了しました。主な変更点は以下の通りです: 1.Rust側: ・keyringクレートを使用して認証情報を保存・取得するコマンドを実装 ・エラーハンドリングを追加 2.フロントエンド側: ・@tauri-apps/apiをインストール ・ログインコンポーネントに認証情報の保存機能を追加 ・エラー表示とローディング状態の管理を追加 これで、以下の機能が利用可能になりました: 1.ユーザーがログインフォームに認証情報を入力 2.認証情報がシステムのキーチェーンに安全に保存される 3.保存された認証情報は後で取得可能 4.エラーが発生した場合はユーザーに通知 5.ローディング中は適切なUIフィードバックを表示 次のステップとして、以下のような機能を追加することができます: 1.認証情報の削除機能 2.認証情報の更新機能 3.複数の認証情報の管理 4.認証情報の暗号化 これらの機能を追加しますか?
いいですね。では確認してみましょうー。
UsernameとPasswordを入力後「Login」ボタン押下。
キーチェーンを確認してみます。
良いですね。キーチェーンに保存されています。
このままでも良いのですがバージョンが古いこともあり、3にあげたいので前回の記事「keyring-rsで、Macのキーチェーンに登録する。」で、記述させていただいたように、
keyring = { version = "3", features = ["apple-native", "windows-native"] }
featuresが必要となるのでそちらも記述。
Cargo.tomlを変更した後、再度動作確認したところ問題なくキーチェーンに保存されておりました。
もう一つだけ処理を追加します。
現状、ログイン情報を入力するとUsernameとPasswordはキーチェーンに保存されるのですが、Tauriを再度起動してしまうと、Usernameが存在しないので、再びログインフォームが表示します。
なので、Usernameを何処かに保存したいのですが。。。
「ログインする際、キーチェーンに情報がある場合はログインフォームはスキップしたい。」
はい、キーチェーンに認証情報がある場合は自動的にログインするように実装しましょう。 まず、Login.vueを修正して、コンポーネントがマウントされた時にキーチェーンから認証情報を取得するようにします:
const handleSubmit = async () => { try { isLoading.value = true; error.value = ""; // 認証情報をキーチェーンに保存 await invoke("save_credentials", { credentials: { username: username.value, password: password.value, }, }); // 最後に使用したユーザー名を保存 localStorage.setItem("lastUsername", username.value); // 親コンポーネントに認証情報を渡す emit("login", { username: username.value, password: password.value, }); } catch (e) { error.value = e instanceof Error ? e.message : "認証情報の保存に失敗しました"; } finally { isLoading.value = false; } };
// コンポーネントマウント時にキーチェーンから認証情報を取得 onMounted(async () => { try { isLoading.value = true; // キーチェーンから認証情報を取得 const savedUsername = await invoke("get_credentials", { username: username.value, }); if (savedUsername) { // 認証情報が見つかった場合、自動的にログイン emit("login", { username: username.value, password: savedUsername, }); } } catch (e) { // エラーは無視(認証情報が存在しない場合) console.log("認証情報が見つかりませんでした"); } finally { isLoading.value = false; } });
と、いった感じに UsernameをlocalStorageに保存して、2回目はその保存したUsernameを参照しキーチェーンにアクセスするように修正しました。
そうしたところ、2回目は無事 Gitクローンを指定する画面から始まりました。
ということで、今回はここまでで、次回はこちらのクローンURLの入力などを実装していこうと思います。今回の修正分はこちらになります。
ではではぁ。
またまたぁ。