2015.10.22
0からはじめるPHP#47【アジャイルで作る掲示板#6-安全なmailto-】
今日一日でめっちゃ研究が進みました。暫くは研究はしなくても良さそうです。(笑)
ということで、英語読んだり論文読んだりといった作業に精を出す予定です。はい。
それはそうとして、今回は
メール送信の話をします。
画像は今作ってる掲示板のプレビューテストです。デザインはテキトーです。
今回目指すところは
後々の管理性を考えてなるべくロジックとデザインを分離するというところにあるので、デザインは後からいくらでも変更できるように作ってます。
<!DOCTYPE HTML>
<html>
<head>
<title>The 人間観察 - </title>
<link rel="stylesheet" type="text/css" href="http://localhost/php/bbs/public/css/style.css">
</head>
<body>
<div id="main">
<div id="header">
</div><!--template_#header-->
<div id="content">
<div id="main_view">
<div class="view_parent">
<span class="content_title">あああ</span><span class="content_pipe">/</span><span class="content_name">え</span>
<span class="content_mail"><a href="./mailto?mail=mycQa97hIgGdpSynhBKu7Q%3D%3D" Target="_blank">[Mail]</a></span> <br>
<div class="content_content">おおおおおおお<br />
<br />
ああああああああああ</div>
<div class="content_footer">20xx/xx/xx xx:xx:xx</div>
</div><!--.view_parent-->
<form name="Form" action="./post" method="post">
以上の内容で送信しますか?<br>
<input type="hidden" name="名前" value="え">
<input type="hidden" name="メール" value="mycQa97hIgGdpSynhBKu7Q==">
<input type="hidden" name="URL" value="">
<input type="hidden" name="件名" value="あああ">
<input type="hidden" name="文字色" value="FF0000">
<input type="hidden" name="色コード" value="">
<input type="hidden" name="本文" value="おおおおおおお
ああああああああああ">
<input type="hidden" name="preview" value="checked">
<input type="hidden" name="confirm" value="confirm">
<input type="submit" value="送信"/>
</form>
</div><!--#main_view-->
</div><!--template_#content-->
<div id="footer">
</div><!--template_#footer-->
</div>
</body>
</html>
例えば上のページのソースはこんな感じになってます。template_がついたdivはテンプレートファイルで使われているので、ここを変えれば全てのページのデザインを変えられます。共通部品なので、急遽divを増やすとかも可能ではあります。
で、それぞれの中身はページごとで別途埋め込まれます。ヘッダー・コンテント・フッターと画面を分けていますが確認画面はコンテント部分しか恐らく使わないので、見た目は普通のページみたくなります。
そして、記事関係は#main_viewで別に指定します。と、こんな風に仕事を分担させてるわけです。
まぁこの辺は各自のセンスの問題だと思います。
さて、メールですね。
一般的に、このようなメール送信機能はHTMLの
mailtoを用いて実装されます。
ただ、この方法はスパムメールの餌食になりやすく、推奨されません。
メールアドレスをエンティティ化するという方法はありますが、HTMLやjavascriptレベルでは安全性はどうしても得られません。まぁやりようはいくらでもあるんですけどね。
そこで「暗号化」の出番です。
<span class="content_mail"><a href="./mailto?mail=mycQa97hIgGdpSynhBKu7Q%3D%3D" Target="_blank">[Mail]</a></span> <br>
先ほどのソースを見てもらうと、こんな風になっています。
暗号化された文字列をmailtoメソッドにgetで送信するわけですね。
ちなみに最初はパラメータとして書いてなかったんですが、スラッシュが入ってバグったのでパラメータにしたんですが、結局アンパサンドとか入るとヤバいことに気づいてエンティティ化してます。
{{$data["件名"]}}/{{$data["名前"]}}
@if(!empty($data["メール"]))
[Mail]@endif @if(empty(!$data["URL"]))
[Home]@endif
{{$data["本文"]}}
実際のプログラムではこんな感じで書かれています。日本語の変数名をそのまま使えるのってびっくりしましたね。使えるもんなんですね。
バリデーションの関係で不格好ですがキーは日本語のままで制作しようかなと思ってます。
$data["メール"]に暗号化された文字列が入ってるので、それをURLに使えるようurlencode()に通してバグらないようにしてます。たぶんこれで大丈夫なはず。
これでスパムメールを送られることもなかろう・・・・・・。人力でやられると流石に無理ですが、それはもう何やっても防ぎようがありません。諦めて下さい。(笑)
private function encrypt($str)
{
/*暗号化*/
return urlencode(openssl_encrypt($str, 'AES-128-ECB', self::KEY));//暗号化
}
private function decrypt($str)
{
/*デコード*/
return openssl_decrypt($str, 'AES-128-ECB', self::KEY);//復号
}
(追記):修正しました。ちなみにデコードの際はurldecodeは必要ないです。(ブラウザ側がデコードします。)
データの暗号化や復号化はこんな感じです。すごい簡単な作りですね。
ロリポップはPHPのバージョンが古くて(なのかどうかは知りませんが)、確か初期ベクトルが必要になった気がするんですが、まぁそんなのはアップロードしてからやれば良いかなと・・・・・・。
復号メソッドはメールのリンクを踏むと呼びだされます。
mailtoというビューに、復号した文字列をwithし送ります。
<html>
<head>
<title>
<META HTTP-EQUIV="Refresh" CONTENT="1;URL=mailto:{{$mail}}">
<script>
function selfClose(time) {
setTimeout('self.close()',time)
}
>/script>
</head>
<body onload="selfClose(10000)">
10秒後に自動的に閉じます
</body>
</head>
</html>
これでメーラーが開くはずです。
昨今ではGmailのようなブラウザでのメーラーもありますので、10秒の猶予を残して閉じるようになってます。流石に10秒あればページ移動するでしょ。
METAタグに関しては拾ってきたものなので特に僕は仕組みを理解していません。こんなのは動けばいいんです。そのうち必要になったらまた調べます。(笑)
プレビュー機能がこれで完成したので、後は大きな課題はレス表示とか、あと
ページネーションですね。
ページネーションは未出の技術で重要なものなので、記事にして復習できるようにするつもりです。(笑)