はじめに
近年、GitHubの代替として注目を集めているオープンソースGitサーバー「Forgejo」。このForgejoのAPIを活用した、実用的なTODOアプリケーションを開発しました。本記事では、その設計思想、技術的な実装、そして実際の使用方法について詳しく解説します。

プロジェクト概要
🎯 開発目的
- Forgejo APIの実践的活用:理論だけでなく、実際に使える形でForgejoのAPIを学習
- セキュアな認証システム:Basic認証とAPIトークンの両方に対応した柔軟な認証
- 実用性の追求:単なるデモではなく、日常的に使えるレベルの機能性
🌟 主な特徴
認証システム
- Forgejoのユーザー名・パスワードでの直接ログイン
- APIトークンを使用した高度な認証
- 認証情報の安全な保存(7日間の有効期限)
TODO管理機能
- 直感的なタスク追加・編集・削除
- 3段階の優先度設定(高・中・低)
- ステータス別・優先度別のフィルタリング
- リアルタイム統計情報の表示
技術的特長
- 完全なクライアントサイド実装
- レスポンシブデザイン対応
- ローカルストレージによるデータ永続化
- モダンなUI/UXデザイン
forgejo のユーザーとパスワードでログインできるアプリできた!!!
これはデカい!!!
*これでforgejo のOpenHand Actionsみたいなコーディングエージェントと連携したアプリが作れるぞ! https://t.co/BQSG3QkZAF pic.twitter.com/GuCGXfI2HW— Maki@Sunwood AI Labs. (@hAru_mAki_ch) June 21, 2025
技術アーキテクチャ
📁 プロジェクト構成
forgejo-auth-todo-app/
├── index.html # メインHTMLファイル
├── style.css # スタイルシート(14.4KB)
├── forgejo-auth.js # Forgejo API認証クラス
├── todo-app.js # TODOアプリケーション管理
├── app.js # メインアプリケーション制御
└── README.md # プロジェクト説明書
🏗️ 設計パターン
1. クラスベース設計
// Forgejo認証を担当
class ForgejoAuth {
async loginWithToken(apiToken, baseUrl) { ... }
async apiRequest(endpoint, options) { ... }
}
// TODO管理を担当
class TodoApp {
addTodo() { ... }
renderTodos() { ... }
updateStats() { ... }
}
2. 責務の分離
ForgejoAuth
:Forgejo APIとの通信・認証管理TodoApp
:TODO機能・UI管理・データ永続化app.js
:アプリケーション全体の制御・画面遷移
核心技術の解説
🔐 認証システムの実装
Basic認証の実装
async function handleSimpleLogin() {
const response = await fetch(`${forgejoUrl}/api/v1/user`, {
method: 'GET',
headers: {
'Authorization': `Basic ${btoa(username + ':' + password)}`,
'Content-Type': 'application/json'
}
});
if (response.ok) {
const userInfo = await response.json();
// 認証成功処理
}
}
APIトークン認証
async loginWithToken(apiToken, baseUrl) {
const response = await fetch(`${this.baseUrl}/api/v1/user`, {
headers: {
'Authorization': `token ${apiToken}`,
'Accept': 'application/json'
}
});
// トークン検証とユーザー情報取得
}
💾 データ管理とローカルストレージ
データ構造設計
const todo = {
id: 'unique_id',
title: 'タスクタイトル',
description: '詳細説明',
priority: 'high|medium|low',
completed: false,
createdAt: '2025-06-21T13:39:15.000Z',
completedAt: null,
updatedAt: '2025-06-21T13:39:15.000Z'
};
永続化とセキュリティ
saveAuth() {
const authData = {
token: this.token,
baseUrl: this.baseUrl,
userInfo: this.userInfo,
timestamp: Date.now()
};
localStorage.setItem('forgejo_auth', JSON.stringify(authData));
}
loadSavedAuth() {
const maxAge = 7 * 24 * 60 * 60 * 1000; // 7日間
if (Date.now() - parsed.timestamp > maxAge) {
this.clearSavedAuth();
throw new Error('認証情報が期限切れです');
}
}
🎨 UI/UXの工夫
レスポンシブデザイン
@media (max-width: 768px) {
.form-row {
grid-template-columns: 1fr;
}
.todo-header {
flex-direction: column;
gap: 10px;
}
}
アニメーションとフィードバック
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.todo-item {
animation: fadeIn 0.5s ease-out;
}
実装上の課題と解決策
🚧 CORS問題への対処
問題:ブラウザからForgejoサーバーへのクロスオリジンリクエストがブロックされる
解決策:Forgejoサーバー側での設定変更
[cors]
ENABLED = true
ALLOW_DOMAIN = localhost:8888,127.0.0.1:8888
METHODS = GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS
ALLOW_CREDENTIALS = true
🔒 セキュリティ考慮事項
認証情報の保護
- Base64エンコーディングによるBasic認証
- 認証情報の有効期限設定(7日間)
- HTTPS通信の推奨
XSS対策
escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
⚡ パフォーマンス最適化
効率的な描画
renderTodos() {
const filteredTodos = this.getFilteredTodos();
todoList.innerHTML = filteredTodos.map(todo =>
this.renderTodoItem(todo)
).join('');
}
メモリ管理
setupTodoItemListeners(todoId) {
// イベントリスナーの適切な設定と削除
buttons.forEach(button => {
button.addEventListener('click', this.handleAction.bind(this));
});
}
使用技術とライブラリ
フロントエンド技術
- HTML5: セマンティックマークアップ
- CSS3: Grid、Flexbox、CSS Animations
- Vanilla JavaScript: ES6+クラス、Async/Await
- Font Awesome 6: アイコンライブラリ
API・認証
- Forgejo REST API: ユーザー情報取得、認証
- Basic Authentication: RFC 7617準拠
- Bearer Token: APIトークン認証
データ管理
- LocalStorage API: クライアントサイドデータ永続化
- JSON: データシリアライゼーション
実際の動作とデモ
📱 ログイン画面
- 2つの認証方式を選択可能
- リアルタイムバリデーション
- 接続テスト機能
🏠 ダッシュボード
- ユーザー情報の表示(アバター、名前)
- 統計情報のリアルタイム更新
- 直感的なTODO管理インターフェース
✅ TODO管理機能
- ワンクリックでの追加・編集・削除
- ドラッグ&ドロップ(将来実装予定)
- エクスポート・インポート機能
今後の展望
🔮 機能拡張計画
Forgejo Issues連携
// 計画中の機能
async syncWithIssues() {
const issues = await this.forgejoAuth.getUserIssues();
// TODOとIssuesの双方向同期
}
チーム機能
- 複数ユーザーでのTODO共有
- 権限管理システム
- リアルタイム同期
高度な機能
- タグ機能によるカテゴリ分類
- 期限設定とリマインダー
- ガントチャート表示
- データ可視化
🌐 対応プラットフォーム拡張
PWA対応
// Service Worker実装予定
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js');
}
Electron版
- デスクトップアプリ化
- オフライン機能強化
- ネイティブ通知
学習価値と応用
💡 学習ポイント
API設計の理解
- RESTful APIの実践的活用
- 認証方式の比較検討
- エラーハンドリングの重要性
フロントエンド設計
- 責務分離の実践
- 状態管理の方法
- ユーザビリティの考慮
セキュリティ意識
- 認証情報の適切な管理
- XSS/CSRF対策
- データ保護の実装
🔧 カスタマイズ例
認証方式の追加
// OAuth2実装例
async loginWithOAuth2(clientId, redirectUri) {
const authUrl = `${this.baseUrl}/oauth2/authorize?` +
`client_id=${clientId}&redirect_uri=${redirectUri}`;
// OAuth2フロー実装
}
外部サービス連携
// GitHub Issues連携例
class GitHubIntegration {
async syncTodosWithIssues() {
// GitHub APIとの連携
}
}
まとめ
このForgejo認証TODOアプリは、単なる技術デモを超えて、実際に使用できるレベルの機能性を持つアプリケーションです。Forgejo APIの活用方法から、モダンなフロントエンド開発のベストプラクティスまで、幅広い技術要素を含んでいます。
主な技術的成果:
- Forgejo APIの実践的活用法の確立
- セキュアな認証システムの実装
- 保守性の高いコード設計の実現
- ユーザビリティを重視したUI/UX設計
このプロジェクトを通じて、オープンソースのGitサーバーであるForgejoの可能性を探求し、実用的なアプリケーション開発の知見を得ることができました。今後もForgejoエコシステムの発展に貢献できるよう、継続的な改善と機能拡張を予定しています。
プロジェクトリポジトリ: GitHub/Forgejo-Auth-TODO-App
ライセンス: MIT License
開発状況: アクティブに開発中
参考リンク
この記事が、Forgejoを活用したアプリケーション開発の参考になれば幸いです。ご質問やフィードバックがありましたら、お気軽にお声かけください。
コメント