2012年02月12日

Movable Typeでのログイン機能実装

MovableTypeでログイン機能を実装する方法を考える。
ブログ記事管理を通常の MT 管理画面上でいつもどおりに行えるようにしたい。
つまり、MT 管理画面上での:
  • ブログ記事の投稿や変更
  • テンプレートの改変
が公開される記事に反映されるようにしたい。

いろいろな方法があると思うが、以下のような仕組みを考えた:
  • ログインが必要なコンテンツは、別ブログに分ける。
  • ブログ記事、ウェブページはウェブ上に公開されない場所に保存させる。
  • ブログ記事は PHP スクリプトから読み出して表示させる。
     (PHP スクリプト上でユーザー認証を行うことで、ログイン機能を実現)
  • PHP 用のテンプレートはウェブページで作成する。
     (ウェブページのデザインテンプレートでデザインを変更できる)

以下、具体的な方法を説明する。

使用した MT バージョンは 5.12-ja。

ブログの作成

ログインを必要とするコンテンツ用のブログを作成する。
その際、[ブログパス] は [絶対パス] にチェックを入れ、ウェブ上に公開されないパスを指定する。

ブログの設定で、
「全般設定」
  • 「アーカイブ設定」-> [ファイルの拡張子] を "tpl" に変更 (これは好みに応じて)
「投稿設定」
  • 「作成の既定値」-> [テキストフォーマット] を "なし" に変更
とする。

デザインテンプレート整備

デザインの「ブログテンプレートの管理」画面で、以下のような設定を行う。
ウェブページテンプレート改変
アーカイブテンプレートの「ウェブページ」テンプレートを改変する。

ウェブページは PHP のデザインテンプレートとして使用するため、ところどころ PHP コードに置き換える必要がある。
ページタイトル
<title><$mt:PageTitle encode_html="1"$> - <$mt:BlogName encode_html="1"$></title>
の部分は記事ごとに変える必要があるので、たとえば
<title><?php echo htmlspecialchars($page_title); ?> - <$mt:BlogName encode_html="1"$></title>
のようにする。

PHP のデザインテンプレートは「ブログ記事」「カテゴリページ」など複数用意することになるので、「ウェブページ」テンプレートはそれらに共通して使えるようにする。
ブログ記事テンプレート改変
アーカイブテンプレートの「ブログ記事」テンプレートを改変する。

ブログ記事は PHP スクリプトから読み出される記事データベース的役割をする。
そのため、読み出しに適した単純な書式で各記事詳細を書き込むようにする。
たとえば:
<$mt:CategoryLabel$>
<$mt:EntryTitle$>
<$mt:EntryDate$>
<$mt:EntryBody$>
など。
今回は議論しないがコメントとタグもブログ記事に書き出すようにする。

また、ブログ記事の URL から記事 ID がわかるように、アーカイブマッピングで [パス] のファイル名部分を %-f から <$MTEntryID$>.html に変更する。
ブログ記事リストテンプレート改変
カテゴリ別や月別のブログ記事リストのテンプレートを改変する。

ブログ記事リストも PHP から読み出されるので、読み出しに適した書式にする。
たとえば:
<mt:Entries limit="$limit">
<$MTEntryDate format="%Y/%m"$>/<$MTEntryID$>:<$MTEntryTitle$>
</mt:Entries>
などとする。

また、アーカイブマッピングの [パス] で、
  • %iindex.html に、
  • %-c%c に、
  • 拡張子を .tpl から .html に、
変更する。
カテゴリリストテンプレート追加
アーカイブテンプレートに、カテゴリリストを出力する「ブログ記事リスト」を追加する。

たとえば、
<MTCategories>
<$MTCategoryBasename$>:<$MTCategoryLabel$>
</MTCategories>
など。

これは、メインインデックスを出力する際に使用する。
インデックステンプレート変更
メインインデックスは直接アクセスしないので削除する。
JavaScript、CSS は [パス] に絶対パスを指定する。
ほか、不要な物は削除。

ウェブページで PHP テンプレート作成

たとえば、以下のようなテンプレートをウェブページとして作成する。
ログイン画面用テンプレート
ファイル名: login.tpl
<h2>ログイン</h2>
<form name="form1" action="/members/index.html" method="post">
<table>
<tr>
<td>メールアドレス</td>
<td><input type="text" name="li_mail" value="<?php echo htmlspecialchars($mail); ?>"/></td>
</tr>
<tr>
<td>パスワード</td>
<td><input type="password" name="li_passwd" value=""/></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="ログイン" /></td>
</tr>
</table>
</form>
メインインデックス用テンプレート
ファイル名: index.tpl
<h2>会員用ページ</h2>
<div class="members">
<?php
foreach ($categories as $category) {
?>
<div><a href="<?php echo htmlspecialchars($category['basename']); ?>/"><?php echo htmlspecialchars($category['label']); ?></a></div>
<?php
}
?>
</div>
カテゴリ別ブログ記事リスト用テンプレート
ファイル名: category.tpl
<h2><?php echo htmlspecialchars($category_label); ?></h2>
<div class="members">
<?php
foreach ($entries as $entry) {
?>
<div><a href="<?php echo htmlspecialchars($entry['path']); ?>.html"><?php echo htmlspecialchars($entry['title']); ?></a></div>
<?php
}
?>
</div>

PHPスクリプトの作成

ページを表示するための PHP スクリプトを用意する。
PHP スクリプトは、記事IDまたはカテゴリIDからブログ記事ファイルのパスを決定し、ファイルの内容を読み出し、デザインテンプレートを選んで表示する処理を行う。

以下の PHP コードはその一例で、view.php というファイル名で対象パス (DocumentRoot/members など) に置く。
<?php
/**
* ページ表示
*
* 入力パラメータ
* c -- 'index' / カテゴリのベースネーム
* y -- 記事年
* m -- 記事月
* e -- 記事番号
* 組み合わせは以下のいずれか
* view.php?c=index
* view.php?c=cat
* view.php?y=2012&m=01&e=00123
*/
// ブログの [ブログパス] で設定したパスを指定
define('MEMBERS_BASEDIR', '/var/www/members');
if (!auth()) {
require MEMBERS_BASEDIR . '/login.tpl';
exit;
}
// 表示ページの決定
if (isset($_REQUEST['c']) && $_REQUEST['c'] != '') {
$category_basename = $_REQUEST['c'];
}
if (isset($_REQUEST['e']) && $_REQUEST['e'] != ''
&& isset($_REQUEST['m']) && $_REQUEST['m'] != ''
&& isset($_REQUEST['y']) && $_REQUEST['y'] != '') {
$entry_year = $_REQUEST['y'];
$entry_month = $_REQUEST['m'];
$entry_id = $_REQUEST['e'];
if (!preg_match('/^\d{4}$/', $entry_year)) {
echo "ERR(1)";
exit;
}
if (!preg_match('/^\d{2}$/', $entry_month)) {
echo "ERR(1)";
exit;
}
} else {
$entry_year = '';
$entry_month = '';
$entry_id = '';
}
} else {
echo "ERR(2)";
exit;
}
// 記事の内容
if ($entry_id != '') {
// 個別の記事
$entry_fname
= MEMBERS_BASEDIR . "/$entry_year/$entry_month/$entry_id.html";
if (!file_exists($entry_fname)) {
echo "ERR(3)";
exit;
}
if (($fh = fopen($entry_fname, 'r')) === FALSE) {
echo "ERR(4)";
exit;
}
flock($fh, LOCK_SH);
$category_label = trim(fgets($fh));
$entry_title = trim(fgets($fh));
$entry_date = trim(fgets($fh));
$entry_contents = '';
while ($row = fgets($fh)) {
$entry_contents .= $row;
}
fclose($fh);
$page_title = $entry_title;
} else if ($category_basename == 'index') {
// インデックス
$categireis = array();
if (($fh = fopen(MEMBERS_BASEDIR . '/categories', 'r')) === FALSE) {
echo "ERR(5)";
exit;
}
flock($fh, LOCK_SH);
while ($row = fgets($fh)) {
$row = trim($row);
if ($row != '') {
list($cbn, $cl) = explode(':', $row, 2);
$categories[] = array('basename' => $cbn,
'label' => $cl);
}
}
fclose($fh);
$page_title = '会員用ページ';
} else {
// カテゴリ
$categirey_label = '';
if (($fh = fopen(MEMBERS_BASEDIR . '/categories', 'r')) === FALSE) {
echo "ERR(5)";
exit;
}
flock($fh, LOCK_SH);
while ($row = fgets($fh)) {
if (preg_match("/^$category_basename:(.+)$/", $row, $matches)) {
$category_label = $matches[1];
break;
}
}
fclose($fh);
if ($category_label == '') {
echo "ERR(6)";
exit;
}
$entries = array();
if (($fh = fopen(MEMBERS_BASEDIR . "/$category_basename/entries", 'r'))
=== FALSE) {
echo "ERR(7)";
exit;
}
flock($fh, LOCK_SH);
while ($row = fgets($fh)) {
$row = trim($row);
if ($row != '') {
list($p, $t) = explode(':', $row, 2);
$entries[] = array('path' => $p,
'title' => $t);
}
}
fclose($fh);
$page_title = $category_label;
}
if ($entry_id != '') {
require MEMBERS_BASEDIR . '/entry.tpl';
} else if ($category_basename == 'index') {
require MEMBERS_BASEDIR . '/index.tpl';
} else {
require MEMBERS_BASEDIR . '/category.tpl';
}
function auth()
{
// ここで認証処理行う
return TRUE;
}
?>

Rewrite設定

Apache の Rewrite エンジンを利用して、ブログ記事や記事リストへのアクセスを view.php にパラメータをつけて転送する。

設定例:
RewriteEngine On
RewriteRule ^index\.html view.php?c=index [L]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)\.html view.php?y=$1&m=$2&e=$3 [L]
RewriteRule ^([^/]+)/index\.html view.php?c=$1 [L]

以上で設定は完了。
タグ:MovableType PHP
posted by K/I at 08:55| 東京 晴れ| Comment(0) | TrackBack(0) | 技術メモ | このブログの読者になる | 更新情報をチェックする

2011年12月03日

ApacheのログをMySQLにはき出す

Apacheのログファイルからアクセス解析するツールを作っていたのだが、アクセス数が多いサイトなのでログファイルのファイルサイズが大きく、読み出してデータベースに書き出すだけで一苦労。
何かよい工夫は無いものか。。。
と思っていたら、こんなものがあった。

mod_log_sql
http://www.outoforder.cc/projects/apache/mod_log_sql/

Apache ログを直接 MySQL に書き出してくれるらしいので、導入してみた。
環境は以下のとおり:

OS: CentOS 5.6
Apache: 2.2.3
MySQL: Ver 14.12 Distrib 5.0.77
mod_log_sql: 1.101

1. インストール


ファイルをダウンロード&解凍して configure
で、いきなりつまずいた。

$ ./configure --with-apxs=/usr/sbin/apxs
configure: creating config.nice
checking for gcc... gcc
checking for C compiler default output... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ANSI C... none needed
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking target system type... x86_64-unknown-linux-gnu
checking for Apache 2.0 version >= 2.0.40... yes
checking for floor in -lm... yes
checking for gzclose in -lz... yes
checking for mysql_init in -lmysqlclient... no
configure: error: libmysqlclient is needed for MySQL support


libmysqlclient が見つからないなら、パスを指定して:
$ ./configure --with-apxs=/usr/sbin/apxs --with-mysql=/usr/lib64/mysql
とすればいい、と思ったが状況改善しない。

調べてみたらこんな記事が:
configure: error: libmysqlclient is needed for MySQL support
http://www.webhostingtalk.com/showthread.php?t=519406

言われるままに:
$ ln -s /usr/lib64/mysql /usr/lib/mysql
$ ./configure --with-apxs=/usr/sbin/apxs

としたらうまくいった。

あとはお決まりの:
$ make
# make install

でインストール完了。

2. MySQLデータベースの準備


ログの格納先データベースを準備する。

$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 6781031
Server version: 5.0.77-log Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> create database apachelogs;
Query OK, 1 row affected (0.09 sec)

mysql> \u apachelogs
Database changed
mysql> \. mod_log_sql-1.101/contrib/create_tables.sql
Query OK, 0 rows affected (0.12 sec)

Query OK, 0 rows affected (0.05 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.10 sec)

Query OK, 0 rows affected (0.01 sec)

mysql> SHOW TABLES;
+----------------------+
| Tables_in_apachelogs |
+----------------------+
| access_log |
| cookies |
| headers_in |
| headers_out |
| notes |
+----------------------+
5 rows in set (0.00 sec)

mysql> CREATE USER apachelogs_user IDENTIFIED BY 'XXXXXXXXXX';
Query OK, 0 rows affected (0.60 sec)

mysql> GRANT INSERT ON apachelogs.* TO 'apachelogs_user'@'localhost'
Query OK, 0 rows affected (0.45 sec)


3. Apache の設定


データベースの準備ができたら、次は Apache の設定。

LoadModule log_sql_module modules/mod_log_sql.so
LoadModule log_sql_mysql_module modules/mod_log_sql_mysql.so
LogSQLLoginInfo mysql://apachelogs_user:XXXXXXXXXX@localhost/apachelogs

<VirtualHost aaa.bbb.ccc.ddd:80>
ServerName www.xxx.yyy
LogSQLTransferLogTable access_log
CustomLog logs/access_log combined
ErrorLog logs/error_log
</VirtualHost>


バーチャルホストごとに書出し先テーブルを指定できるようになっている。

Apache を再起動。

# service httpd graceful

設定が反映される。
ログは、ログファイルとデータベースの両方にはき出される。
posted by K/I at 20:31| 東京 曇り| Comment(0) | TrackBack(0) | 技術メモ | このブログの読者になる | 更新情報をチェックする

2011年04月07日

Redmineのインストール

これまで trac を使っていたが、Redmine を使ってみることにした。
以下、インストールメモ。

インストールした環境は、Fedora 14。
インストールした Redmine のバージョンは 1.1.2。

Redmine.JP に掲載されているインストール手順を参考に作業した。
http://redmine.jp/guide/RedmineInstall/

(1) 必要なツール類のインストール
Ruby, Rails, Rack のバージョンは、記載されているバージョンと完全に一致していないといけないようだ。

Fedora 14 のパッケージは、Rails と Rack のバージョンが一致しなかった。
今回、Redmine の公式リリース版をダウンロードしたが、Rails は Redmine のファイル一式に含まれていたが、Rack は含まれていなかったので必要なバージョンを gem でインストールした。
gem install rack -v=1.0.1

(2) Redmine 用アカウント作成

Redmine 用アカウント redmine を作成。

# useradd redmine

(3) データベースの準備

データベースは、今回は PostgreSQL を使用した (使い慣れているので)。

Redmine 用のロールとデータベースを作成する。

CREATE ROLE redmine LOGIN ENCRYPTED PASSWORD 'パスワード' NOINHERIT VALID UNTIL 'infinity';
CREATE DATABASE redmine WITH ENCODING='UTF8' OWNER=redmine;


そして、redmine をインストールするサーバーからのアクセスを許可させる。
同一ホストであっても、ローカルからのアクセスが ident メソッドのみになっている場合は、自IPアドレスから password メソッドでの host アクセスを許可させておく (/var/lib/pgsql/data/pg_hba.conf および /var/lib/pgsql/data/postgresql.conf を設定)。

(4) ダウンロード

以下のサイトから、Redmine のファイルをダウンロード。
http://www.redmine.jp/download/

レポジトリからチェックアウトもできるが、上述のとおり Rails の必要バージョンが含まれているという理由から、tar ファイルをダウンロードした。

tar ファイルを適当なところ (たとえば /usr/local の下とか) に解凍し、オーナーを redmine にする (←オーナー変更は必要なかったかも)。

# chown -R redmine: redmine-1.1.2

(5) セッションストア秘密鍵の生成

redmine アカウントでログインし、解凍したディレクトリ (たとえば、/usr/local/redmine-1.1.2。以下、Redmine ディレクトリと呼ぶ) に移動し、以下のコマンドを実行する。

# rake config/initializers/session_store.rb

(6) テーブル作成

解凍ファイルの中にある config/database.yml.exampleconfig/database.yml にコピーし、production: のところの内容を変更する。
production:
  adapter: postgresql
  database: redmine
  host: IPアドレスかホスト名
  username: redmine
  password: "redmine ロールのパスワード"


そして、Redmine ディレクトリで、以下のコマンドを実行:

rake db:migrate RAILS_ENV="production"
rake redmine:load_default_data RAILS_ENV="production"

redmine データベース内にテーブル等が作られる。

(7) 動作確認

以下のコマンドを実行してWebサーバーを起動:

# ruby script/server webrick -e production

http://localhost:3000/ にアクセスして Welcome 画面が表示されるか確認する。

(8) Passenger (mod_rails) を導入

Redmin.JP サイトに webrick は「開発用」なので「動作確認以外には使用するな」という脅し文句が書かれているので、Passenger をインストールしてみる。
まずは、必要なパッケージをインストール。
# yum install rubygem-fastthread
# yum install rubygem-daemons

場合によってはほかのパッケージが必要かもしれない。
Passenger 自体は rpm が用意されていなかったので、gem でインストール。
# gem install passenger
Passenger Apache 2モジュールのインストーラーを実行。
# passenger-install-apache2-module
ところが、なぜか
/usr/lib/ruby/gems/1.8/gems/passenger-3.0.6/lib/phusion_passenger/platform_info/apache.rb:277:in `_unmemoized_apr_config_needed_for_building_apache_modules?': undefined local variable or method `test_exe_outdir' for PhusionPassenger::PlatformInfo:Module (NameError)
        from /usr/lib/ruby/gems/1.8/gems/passenger-3.0.6/lib/phusion_passenger/platform_info.rb:92:in `apr_config_needed_for_building_apache_modules?'
        from /usr/lib/ruby/gems/1.8/gems/passenger-3.0.6/bin/passenger-install-apache2-module:69:in `dependencies'
        from /usr/lib/ruby/gems/1.8/gems/passenger-3.0.6/lib/phusion_passenger/abstract_installer.rb:166:in `check_dependencies'
        from /usr/lib/ruby/gems/1.8/gems/passenger-3.0.6/bin/passenger-install-apache2-module:90:in `install!'
        from /usr/lib/ruby/gems/1.8/gems/passenger-3.0.6/lib/phusion_passenger/abstract_installer.rb:63:in `start'
        from /usr/lib/ruby/gems/1.8/gems/passenger-3.0.6/bin/passenger-install-apache2-module:236
        from /usr/bin/passenger-install-apache2-module:19:in `load'
        from /usr/bin/passenger-install-apache2-module:19

とかいうエラーが出てうまくいかない。
これはどうやら、typoらしい。
/usr/lib/ruby/gems/1.8/gems/passenger-3.0.6/lib/phusion_passenger/platform_info/apache.rb を開き、"test_exe_outdir" を "tmpexedir" に変更してリトライ。
不足しているソフトウェアを提示してくれる (しかも、実行すべき yum コマンドまで教えてくれる!) ので、インストール後再実行。
起動できた。

(9) Apache 設定

Apache に Passenger の設定を追加。
たとえば、/etc/httpd/conf.d/passenger.conf を作成して、passenger-install-apache2-module 実行時に表示された設定を記載する。
今回の環境では以下のとおり:
LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-3.0.6/ext/apache2/mod_passenger.so
PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-3.0.6
PassengerRuby /usr/bin/ruby


次に、Redmine の設定を行う。
ポート 20080 にアクセスするとRedmineが表示されるようにVirtualHost設定することにした。
たとえば /etc/httpd/conf.d/redmine.conf に記載する。
今回の環境では以下のようにする:
Listen 20080
NameVirtualHost *:20080
<VirtualHost *:20080>
    ServerAdmin webmaster@aaa.bbb.ccc
    DocumentRoot /usr/local/redmine-1.1.2/public
    CustomLog /var/www/vhosts/logs/redmine_ssl_access-log combined
    LogLevel warn
    ErrorLog /var/www/vhosts/logs/redmine_ssl_error-log
</VirtualHost>

そして、Redmine ディレクトリのオーナーを apache:apache に変更する。
今回の環境では:
# chown -R apache: /usr/local/redmine-1.1.2

Apacheを再起動すると、http://localhost:20080/ でアクセスできる。

(10) メール送信設定

プロジェクトで発生したイベントをメールで送信するようにするには、Redmine ディレクトリの config/email.yml.exampleconfig/email.yml にコピーし、設定変更する。
たとえば localhost を SMTP サーバーにするには、production: のところを
production:
  delivery_method: :smtp
  smtp_settings:
    address: localhost
    port: 25
    domain: メールドメイン名

のように設定する。
タグ:redmine
posted by K/I at 21:20| 東京 晴れ| Comment(0) | TrackBack(0) | 技術メモ | このブログの読者になる | 更新情報をチェックする

2011年03月14日

節電ポスター ブログパーツ

今回の東北地方の震災での節電をよびかけるポスターが、「節電ポスター」( http://setsuden.tumblr.com/ ) というサイトで提供されています。
これは、節電を呼びかけるポスターを印刷してあちこちに貼りましょう、というものです。

これをブログパーツ化したものを作成しましたのでお知らせします。

「節電ポスター」ブログパーツ
http://tan9.net/psvc/setsuden.js

ブログに貼る場合は、以下のようにします。
<script type="text/javascript" src="http://tan9.net/psvc/setsuden.js?wd=253&ht=358&bgcol=&brdrcol=&updt=1&intvl=8&rndm=0"></script>
wd画像横幅の最大値 (0なら無制限)
ht画像高さの最大値 (0なら無制限)
bgcol表示エリアの背景色 (ccccccなど、#は付けない)
brdrcol表示エリアの枠の色 (ccccccなど、#は付けない)
updt画像自動更新フラグ (0: 自動更新しない、1: 自動更新する)
intvl画像の更新周期 (単位: 秒)
rndmランダム再生フラグ (0: シーケンス再生、1: ランダム再生)

wdht の両方に 0 以上の値を指定した場合、表示エリアは横幅wdピクセル、高さ htピクセルの大きさに固定され、画像はエリア内最大の大きさ (縦横比は保持) に縮小/拡大されます。

なお、画像URLなどはハードコーディングしているので、サイトの画像投稿は自動反映されません。

【2011年3月20日更新】
・ht, wd, bgcol, brdrcol パラメータを追加
posted by K/I at 09:38| 東京 晴れ| Comment(0) | TrackBack(2) | 日記 | このブログの読者になる | 更新情報をチェックする

2011年02月26日

もくもく日記: IS03で実機デバッグ環境整備

第六回日本Androidの会埼玉支部ワークショップ

開催日: 2011-02-26

今回の自分のもくもくテーマ: IS03で実機デバッグ環境整備

(1) IS03 のドライバーをインストール

ドライバーをダウンロードしてインストール。
『IS03 用USB ドライバ - SHARP』
http://k-tai.sharp.co.jp/support/a/is03/download/usb/

(2) IS03 を接続

USB接続モードを「高速転送モード」にすると、ドライバーのインストールがはじまる。
ところが、Android ADB Interface のドライバーインストールに失敗。

そこで。。。

(3) SDK ManagerでGoogle Usb Driver packageをインストール

これでもドライバーインストール失敗。
(これは必要だったのか?)

調べたら、IS03 専用のドライバーが必要だった。

(4) IS03 用のADB USBドライバをダウンロード

https://sh-dev.sharp.co.jp/android/modules/driver/index.php?/is03_adb/download

ドライバー更新して、ダウンロードしたドライバを指定したらうまくいった。

(5) SDK Manager でいろいろ更新したら、Eclipse の ADT のバージョンと合わなくなったので、そちらも更新。

EclipseからRunしたら、めでたくIS03上に表示された。

今回はここまで。
タグ:android
posted by K/I at 17:01| 東京 晴れ| Comment(0) | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2010年11月01日

電子証明書によるクライアント認証 (Apache)

銀行の企業向けインターネットバンキングなどで、よく「デジタル証明書」を使ってユーザー認証しているものがあるが、あれはどうやっているのだろうか?
ちょっと調べてみた。

Web サーバーが信頼する CA から発行した証明書を保有するクライアント (Webブラウザ) のみを信頼する、というのが「クライアント認証」の考え方のようだ。

ここでは、CA は自前で用意してあるものとする。
以下、以前まとめた下の関連記事の設定を前提に話を進める。
【関連記事】
PKI の認証局(CA)を構築する

【Webサーバー側】

(1) 信頼する CA の設定

まず、信頼する CA の一覧を設定する。
CA から、CA 証明書 (cacert.pem) を受け取り、Apache に以下のように設定する。
SSLVerifyClient require
SSLCACertificateFile cacert.pem のパス

複数の CA 証明書がある場合には、ディレクトリで指定できる。
SSLVerifyClient require
SSLCACertificatePath CA 証明書の設置ディレクトリ

設定したら Apache を再起動する。

(2) 秘密鍵+証明書署名要求ファイルの作成

※この処理は、Web サーバーで行うのか、CA で行うのか、あるいはクライアント側で行うのかは、サービスの運営方針によるのではないか? と思う。
クライアントの秘密鍵と証明書署名要求 (CSR) の両方を含む PEM 形式のファイルを作成する。
Country Name などに入力する値は、CA のものに合わせる。
# openssl req -new -keyout user01.pem -out user01.pem
Generating a 2048 bit RSA private key
.........+++
...+++
writing new private key to 'user01.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:JP
State or Province Name (full name) []:Tokyo
Locality Name (eg, city) [Default City]:Shinjuku-ku
Organization Name (eg, company) [Default Company Ltd]:K-ISHIK
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:k.ishikawa
Email Address []:k-ishik@camel.zoo.park

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:


なお、CA 証明書 の内容は以下のようなコマンドで表示できる。
# openssl x509 -in CA証明書ファイル -text

【CA側】
以下の (3)、(4) の手順で、PKCS #12 形式のクライアント証明書を発行する

(3) 署名付き秘密鍵ファイルの作成

作成した秘密鍵+証明書署名要求を CA にコピーし、証明書ファイルを作成する。
# openssl ca -in user01.pem -keyfile /etc/pki/CA/private/cakey.pem \
-cert /etc/pki/CA/cacert.pem -out user01.crt
Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for /etc/pki/CA/private/cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number: 14 (0xe)
Validity
Not Before: Oct 31 15:05:37 2010 GMT
Not After : Oct 31 15:05:37 2011 GMT
Subject:
countryName = JP
stateOrProvinceName = Tokyo
organizationName = K-ISHIK
organizationalUnitName =
commonName = k.ishikawa
emailAddress = k-ishik@camel.zoo.park
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
A7:EC:D2:85:9F:59:4A:A0:B4:96:81:F6:68:5B:D8:49:69:81:7E:FA
X509v3 Authority Key Identifier:
keyid:2B:45:1F:EE:3B:DF:57:65:41:24:C9:04:53:AD:F1:B5:BA:80:D6:DA

Certificate is to be certified until Oct 31 15:05:37 2011 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

これにより、PEM 形式の証明書ファイル user01.crt が作成される。

(4) PKCS #12 形式の証明書ファイルの作成

秘密鍵+証明書署名要求ファイルと PEM 形式の証明書ファイルから PKCS #12 形式の個人証明書を作成する。
# openssl pkcs12 -export -clcerts -in user01.crt -inkey user01.pem \
-out user01.p12
Enter pass phrase for user01.pem:
Enter Export Password:
Verifying - Enter Export Password:


【クライアント側】

(5) 証明書のインポート

CA (または、Web サーバー経由で) PKCS #12 形式の個人証明書 user01.p12 をクライアント PC にコピーし、ブラウザにインポートする。
(以下、Internet Explorer 7 の場合)
  1. [ツール] メニューの [インターネットオプション] の [コンテンツ] タブで、[証明書] ボタンをクリックする。
    電子証明書のインストール#1
  2. "証明書" 画面の [個人] タブで、[インポート] ボタンをクリックする。
    電子証明書のインストール#2
  3. "証明書のインポート ウィザード" が起動する。[次へ] をクリックする。
    電子証明書のインストール#3
  4. [ファイル名] 欄に個人証明書のパスを設定し、[次へ] ボタンをクリックする。
    電子証明書のインストール#4
  5. [パスワード] 欄に、手順 (4) で入力した Export Password を入力する。
    [秘密キーの保護を強力にする] にチェックを入れると、ブラウザ起動後最初に対象サイトにアクセスするたびにパスワードの入力を求められる。
    [このキーをエクスポート可能にする] にチェックを入れると、"証明書" 画面でキーのエクスポートができるようになる。
    電子証明書のインストール#5
  6. あとは、指示に従って処理する。
    電子証明書のインストール#6
    電子証明書のインストール#7

以上で、設定は完了。
クライアント認証するように設定した URL にアクセスすると、"デジタル証明書の選択" ダイアログが表示される。
電子証明書のインストール#8
インストールした証明書を選択して [OK] をクリックすればアクセスできる。
タグ:PKI CA
posted by K/I at 01:16| 東京 雨| Comment(0) | TrackBack(0) | 技術メモ | このブログの読者になる | 更新情報をチェックする

2010年10月21日

PostgreSQL 8.3 から 8.4 への移行

Fedora を 10 から 12 にアップグレードしたら、PostgreSQL が起動しなくなった。
PostgreSQL のバージョンが 8.3 から 8.4 にバージョンアップしたため、データベースファイルが対応しなくなったからだ。
すでに 8.4 にアップグレードされているから PostgreSQL も起動しないので、pg_dump もできない。
しかたなく、8.3 環境を用意して /var/lib/pgsql/data ディレクトリをごっそりそちらにコピーし、pg_dumpall した。
この移行作業のめんどくささはなんとかならないものか?
ほかの人はどうやって対応しているのだろうか。

ちなみに、たまたまインストールしてあった Ubunto では、コピーした data ディレクトリでうまく動作しなかった。
Fedora 11 でもダメで、Fedora 10 にしたらうまくいった。
Ubundo は設定がいろいろ違っていて合わせるのが面倒だったので断念。
Fedora 11 がダメだった理由は不明。
posted by K/I at 12:12| 東京 霧| Comment(0) | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする

2010年08月01日

HTML5 のフォーム関連タグ

【関連記事】
HTML4/XHTML1 から HTML5 への変更点
HTML5 のセクション関連タグ
HTML5 のコンテンツグループ化関連タグ
HTML5 のテキストの意味付け関連タグ
HTML5 の埋め込みコンテンツ関連タグ
●参考
4.10 Forms - HTML5

追加されたフォーム関連要素

要素 カテゴリ タグ内に含むもの 説明
datalist flow content
phrasing content
phrasing content
または
0 個以上の option 要素
input 要素で使われる選択肢を定義する。
output flow content
phrasing content
listed, labelable, and resettable
form-associated element
phrasing content 計算結果を表す。
計算自体は、JavaScript などを使って処理する。

変更された属性 (グローバル属性を除く)

要素名 属性名 説明
form novalidate ブール属性。
指定すると、サブミットの際にフォームの正当性チェックが行われない。
fieldset form 関連づけされる form 要素の ID を指定する。
デフォルトでは、すぐ上のレベルの form 要素に関連づけされる。
disabled 指定すると、子ノードのフォーム・コントロールが無効状態になる (最初の legend 要素を除く)。
input type 以下の値が追加された。
search
text とほぼ同様。
プラットフォームによっては、検索フィールドが通常の入力欄と形状が異なる場合があるので、それに対応するためのもの。
tel
電話番号の入力欄。
url
絶対 URL の入力欄。
email
メールアドレスの入力欄。
datetime
日時の入力欄 (UTC)。
date
日付の入力欄。
month
月の入力欄。
week
曜日の入力欄。
time
時刻の入力欄。
datetime-local
日時の入力欄 (現地時刻)。
number
数値の入力欄。
range
目盛りなど、一定の範囲から数値を取得するフォーム・コントロールを表示させる。
color
カラーパレットなど、色を表す文字列を取得するフォーム・コントロールを表示させる。
form (既述)
autofocus ブール属性。
指定すると、ページの表示時にそのフォーム・コントロールにフォーカスが移る。
autocomplete 以下のいずれかを指定する。
on
キーワード・マッピングをオンにする。
off
キーワード・マッピングをオフにする。
値無し
デフォルト状態にする (関連づけられている form 要素の autocomplete の値。form 要素の autocomplete のデフォルト値は on)。
この属性を指定しない場合はデフォルト状態となる。
list あらかじめ定義しておいた選択肢一覧 datalist 要素の ID を指定する。
required ブール属性。
指定するとその要素は必須となり、サブミット時にチェックされる。
multiple ブール属性。
ユーザーが複数の値を指定できることを表す。
pattern フォーム・コントロールの value をチェックするための正規表現。
min 最小値。
値が数値の場合、その値が最小値となる。
値が数値でない場合、type 属性の現在の状態からデフォルトの最小値が決定されれば、その値が最小値となる。
いずれでもない場合、最小値は無しとなる。
サブミットの際、ユーザーが入力した値が数値の場合、最小値より小さいかどうかチェックされる。
max 最大値。
内容は min 属性と同様。
step 取りうる数値の階差。
ベース値は、もし最小値が設定されていればその値。最小値が無い場合、デフォルトのベース値が設定されていればその値。それが無ければ 0。
placeholder ユーザーがデータ入力する際の補助となる短めのヒント。
入力する値のサンプルや、短い説明を記述しておく。
改行コードは使用できない。
label 属性とは異なる。
output
※新規
for 計算に使われたり、計算に影響を与えたりする要素を、明示的に示す。
form (既述)
name 要素名。

W3C サイトに書かれていた例を引用。
(1) input 要素の pattern 属性の例
<label> Part number:
<input pattern="[0-9][A-Z]{3}" name="part"
title="A part number is a digit followed by three uppercase letters."/>
</label>
(2) datalist 要素の例
<input type="url" name="location" list="urls">
<datalist id="urls">
<option label="MIME: Format of Internet Message Bodies" value="http://www.ietf.org/rfc/rfc2045">
<option label="HTML 4.01 Specification" value="http://www.w3.org/TR/html4/">
<option label="Form Controls" value="http://www.w3.org/TR/xforms/slice8.html#ui-commonelems-hint">
<option label="Scalable Vector Graphics (SVG) 1.1 Specification" value="http://www.w3.org/TR/SVG/">
<option label="Feature Sets - SVG 1.1 - 20030114" value="http://www.w3.org/TR/SVG/feature.html">
<option label="The Single UNIX Specification, Version 3" value="http://www.unix-systems.org/version3/">
</datalist>
(3) output要素の例
<form onsubmit="return false">
<input name=a type=number step=any> +
<input name=b type=number step=any> =
<output onforminput="value = a.valueAsNumber + b.valueAsNumber"></output>
</form>
タグ:HTML5
posted by K/I at 08:05| 東京 霧| Comment(0) | TrackBack(0) | 技術メモ | このブログの読者になる | 更新情報をチェックする

2010年07月29日

HTML5 のテキストの意味付け関連タグ

【関連記事】
HTML4/XHTML1 から HTML5 への変更点
HTML5 のセクション関連タグ
HTML5 のコンテンツグループ化関連タグ
HTML5 の埋め込みコンテンツ関連タグ
HTML5 のフォーム関連タグ
●参考
4.6 Text-level semantics - HTML5

テキストの意味付け関連要素一覧

要素 カテゴリ タグ内に含むもの 説明
time flow content
phrasing content
phrasing content (time 要素を除く) 時刻または日付 (時刻とタイムゾーンをつけてもよい) を表す。
mark flow content
phrasing content
phrasing content テキストの一部を強調表示するのに使う。
emstrong と異なり、本来の文章の意図とは別の意味付けから強調したい場合に用いる (あとから蛍光ペンでマーカーをつける感覚)。
たとえば以下の状況で使われる。
  • 引用した文の一部を強調表示 (もともとは強調表示されていない) → 例の (2) 参照
  • ユーザーの操作に関連が深い部分を強調表示 (検索結果での検索語の強調表示、エラー出力のエラー箇所の表示など)
ruby flow content
phrasing content
phrasing content の後に rt 要素 1 つ
または
rp 要素 1 つと rt 要素 1 つと別の rp 要素 1 つを組み合わせたグループ 1 つ以上
ルビを振る。
rt なし phrasing content
rp なし phrasing content
wbr flow content
phrasing content
なし 改行可能位置を示す。

time 要素の属性 (グローバル属性を除く)

属性名 説明
datetime 日付または時刻を表す。
この属性が指定されない場合、日付または時刻は要素の内容で指定される。
  • 日付が必須で datetime 属性が存在する場合、その値は有効な日付を表す文字列でなければならない (時刻はオプション)。
  • 日付が必須で datetiime 属性が存在しない場合、要素の内容は有効な日付を表す文字列でなければならない (時刻はオプション)。
  • 日付が必須でなく、datetime 属性が存在する場合、その値は有効な日付または時刻を表す文字列でなければならない。
  • 日付が必須でなく、datetime 属性が存在しない場合、要素の内容は有効な日付または時刻を表す文字列でなければならない。
日付は、グレゴリオ暦で表す。
pubdate ブール属性。
指定すると、直近の親の article 要素の発行日時を表す。article 要素が存在しなければ、文書全体の発行日時となる。
この属性を指定した場合、日付は必須。
article 要素または文書に対して、pubdate 属性を持つ time 要素は複数指定できない。

W3C の仕様書から、いくつか例を引用。
(1) time 要素を使った hCalendar の例
<div class="vevent">
<a class="url" href="http://www.web2con.com/">http://www.web2con.com/</a>
<span class="summary">Web 2.0 Conference</span>:
<time class="dtstart" datetime="2007-10-05">10月5日</time> -
<time class="dtend" datetime="2007-10-20">19日</time>、
<span class="location">アージェント・ホテル (カリフォルニア州サンフランシスコ)</span>にて
</div>
(2) mark で強調表示する例
<p lang="en-US">Consider the following quote:</p>
<blockquote lang="en-GB">
<p>Look around and you will find, no-one's really
<mark>colour</mark> blind.</p>
</blockquote>
<p lang="en-US">As we can tell from the <em>spelling</em> of the word,
the person writing this quote is clearly not American.</p>
(3) ルビの例
<ruby>
漢 <rp>(</rp><rt>かん</rt><rp>)</rp>
字 <rp>(</rp><rt>じ</rt><rp>)</rp>
</ruby>
(4) wbr を使って長い1語を途中改行できるようにした例
<p>So then he pointed at the tiger and screamed
"there<wbr>is<wbr>no<wbr>way<wbr>you<wbr>are<wbr>ever<wbr>going<wbr>to<wbr>catch<wbr>me"!</p>
タグ:HTML5
posted by K/I at 11:14| 東京 晴れ| Comment(0) | TrackBack(0) | 技術メモ | このブログの読者になる | 更新情報をチェックする

2010年07月26日

HTML5 のコンテンツグループ化関連タグ

【関連記事】
HTML4/XHTML1 から HTML5 への変更点
HTML5 のセクション関連タグ
HTML5 のテキストの意味付け関連タグ
HTML5 の埋め込みコンテンツ関連タグ
HTML5 のフォーム関連タグ
●参考
4.5 Grouping content - HTML5

コンテンツグループ化関連要素一覧

要素 カテゴリ タグ内に含むもの 説明
figure flow content
sectioning root
次のいずれか。
  • figcaption 1 つと、その後に flow content
  • flow content と、その後に 1 つの figcaption
  • flow content
自己完結していて、通常は本文から参照されるもの。
たとえば、注釈のイラスト、図表、写真、コードリストなどに使われる。
本文から分離したところ (サイドバー、別ウィンドウ、付録など) に表示してもよい。
figcaption なし flow content figure 要素を説明するもの。

figurefigcaption 要素の属性 (グローバル属性を除く)

figurefigcaption 要素の属性は、グローバル属性のみ。

W3C に書かれていた例をいくつか。
まずは、コードリストの例。
<p>基本的なコアインターフェース API の定義については、<a href="#l4">リスト 4</a> を参照のこと。</p>
<figure id="l4">
<figcaption>リスト 4: 基本的なコアインターフェース API の定義</figcaption>
<pre><code>interface PrimaryCore {
boolean verifyDataLine();
void sendData(in sequence&lt;byte> data);
void initSelfDestruct();
}</code></pre>
</figure>
<p>API は、UTF-8 を使用するように設計されている。</p>
次は、figure ではない図と、figure である図・映像の例。
<h2>Malinko のコミック</h2>
<p>この事例では、コミックに関するある種の「知的財産」侵害に焦点が当て
られた (証拠物件 A 参照)。この訴訟では、以下の言葉で終わる予告編映像を
追及している。
<blockquote>
<img src="promblem-packed-action.png" alt="ラフコピー! この行為は問題満載!">
</blockquote>
<p>...が放送された。弁護士は Bigger 社製のノート PC という武器を手に、
雪ダルマ式戦法で先制攻撃を開始した。予告編は、証拠物件 B で全映像を閲
覧できる。
<figure>
<img src="ex-a.png" alt="汚れた紙に書かれた走り書き。">
<figcaption>証拠物件 A: 提示されたコミックの<cite>ラフコピー</cite></figcaption>
</figure>
<figure>
<video src="ex-b.mov"></video>
<figcaption>証拠物件 B: <cite>ラフコピー</cite>予告編映像</figcaption>
</figure>
<p>この事例は、法廷外で解決した。
タグ:HTML5
posted by K/I at 07:07| 東京 曇り| Comment(0) | TrackBack(0) | 技術メモ | このブログの読者になる | 更新情報をチェックする

広告


この広告は60日以上更新がないブログに表示がされております。

以下のいずれかの方法で非表示にすることが可能です。

・記事の投稿、編集をおこなう
・マイブログの【設定】 > 【広告設定】 より、「60日間更新が無い場合」 の 「広告を表示しない」にチェックを入れて保存する。