はじめに
AWSにはAmazonCognitoという認証サービスがあります。
Amazon Cognito
Cognitoを利用することで面倒だった認証周りの実装が、マネージドでかつサーバレスで利用することができるので、かなり重宝しています。
( Experess.jsでアプリケーション構築してときはpassportというプラグインを使ってかなりしんどかった… )
しかもCognitoは、ユーザーの検証(Verify)メールを送信させることができます。
ユーザー登録時にメールアドレスを登録させるようにして、そのアドレスに検証リンクや検証コードを送信して、リンクを踏んだり、コードを入力することでユーザーを有効化することができます。
私が構築しているアプリケーションでも、ユーザー登録時に検証メールを送信して、検証リンクを踏むまでユーザーが有効化しようとしていました。
化ける日本語たち
これはアカウント有効化メールです。
下記リンクをクリックしアカウントを有効化してください。
Verify Email
こんな文面のメールを送信すべくCognitoのコンソール画面から設定しました。
さぁ、検証メールよ送信されよ!と意気揚々に送信してみましたが……
?????????????????
???????????????????????????
Verify Email
と、このようにきれいに日本語は文字化けしました。
原因はなんだ
悩んでいると頼れる後輩くんが
「メールのソースを見ましょう」
とよくわからないことを言ってきたので、とりあえずソースを確認してみると、下記のようなテキストでした。
Subject: =?UTF-8?B?SW9ULmt5b3RvIFZJUyDjgqI=?=
=?UTF-8?B?44Kr44Km44Oz44OI55m76Yyy44GC44KK?=
=?UTF-8?B?44GM44Go44GG44GU44GW44GE44G+44GZ?=
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="----=_Part_554_2126041111.1535085176849"
user_pool_name: xxxxxxxxxxx
region: ap-northeast-1
Date: Fri, 24 Aug 2018 04:32:57 +0000
X-SES-Outgoing: 2018.08.24-54.240.27.61
Feedback-ID: 1.us-west-2.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=:AmazonSES
------=_Part_554_2126041111.1535085176849
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div>?????????????????</div>
<div>???????????????????????????</div>
<div> <a href=https://confirm-xxxxxx.auth.ap-northeast-1.amazoncognito.com/confirmUser?client_id=5dvt2i0dkqm50626f2ug9poto1&user_name=xxxxxxxx&confirmation_code=123456>Verify Email</a> </div>
</body>
</html>
------=_Part_554_2126041111.1535085176849--
※一部抜粋。一部マスクしています。
ここで?となったのはまずMINEが Content-Type: multipart/mixed
になっていること。
そしてどうやら2つめのPartにメールの本文が書かれているようなのですが、 charset=us-ascii
になっているではありませんか…
そりゃ日本語が見事に化けるわけですよ。
Cognitoの検証メールはSESで送信してきているみたいなので、SESの仕様をあさっていると、
フォーマットされた E メールを送信する場合、送信元アドレス、宛先アドレス、メッセージの件名、およびメッセージ本文を指定する必要があります。
Amazon SES では、E メールクライアントソフトウェアでの表示に最適化された、適切にフォーマットされたマルチパート MIME メールメッセージを
自動的にアセンブルします。
という一文を見つけました。
おそらくCognitoで登録している本文の1文字目を見て、文字コードをよしなに解釈したり、マルチパートにしたりしてくれているんだろうなーとぼんやり思いました。SESすげぇ…
で、なにしたのか
結論から言うと、改行コードを打ち込んでやりました。
そうすると1文字目が改行コードになるので、変にマルチパートで送信されることなくメールが送信されました。
やったね!!
これはアカウント有効化メールです。
下記リンクをクリックしアカウントを有効化してください。
Verify Email
メールのソースはこんな感じ
Subject: =?UTF-8?B?SW9ULmt5b3RvIFZJUyDjgqI=?=
=?UTF-8?B?44Kr44Km44Oz44OI55m76Yyy44GC44KK?=
=?UTF-8?B?44GM44Go44GG44GU44GW44GE44G+44GZ?=
MIME-Version: 1.0
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Message-ID: <010101656a38fce0-ecd85a66-c586-43a6-8e47-30b64a4776f9-000000@us-west-2.amazonses.com>
Date: Fri, 24 Aug 2018 04:37:24 +0000
X-SES-Outgoing: 2018.08.24-54.240.27.62
Feedback-ID: 1.us-west-2.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=:AmazonSES
<!DOCTYPE html>
<html>
<head>
<meta charset=3D"utf-8">
</head>
<body>
<div>=E3=81=93=E3=82=8C=E3=81=AF=E3=82=A2=E3=82=AB=E3=82=A6=E3=83=
=B3=E3=83=88=E6=9C=89=E5=8A=B9=E5=8C=96=E3=83=A1=E3=83=BC=E3=83=AB=E3=81=A7=
=E3=81=99=E3=80=82</div>
<div>=E4=B8=8B=E8=A8=98=E3=83=AA=E3=83=B3=E3=82=AF=E3=82=92=E3=82=
=AF=E3=83=AA=E3=83=83=E3=82=AF=E3=81=97=E3=82=A2=E3=82=AB=E3=82=A6=E3=83=B3=
=E3=83=88=E3=82=92=E6=9C=89=E5=8A=B9=E5=8C=96=E3=81=97=E3=81=A6=E3=81=8F=E3=
=81=A0=E3=81=95=E3=81=84=E3=80=82</div>
<div> <a href=https://confirm-xxxxxx.auth.ap-northeast-1.amazoncognito.com/confirmUser?client_id=5dvt2i0dkqm50626f2ug9poto1&user_name=xxxxxxxx&confirmation_code=123456>Verify Email</a> </div>
</body>
</html>
さいごに
こうして日本語が化けることなく検証メールを送信することができました。
根本的な解決に至ったわけではないので、時間があればもっと掘り下げていきたいなと思います。
またメール本文にHTMLが書けるので、ある程度メール本文をデコレーションすることができるのでいい感じの検証メールを作れるなと感じました。
何はともあれ、Cognitoを利用すると、ユーザー用のDBを持つ必要もなくなるし、Cognitoで発行したトークンを使ってその他サービスのアクセスをコントロールすることができたりするのでとても便利なサービスですね!
一緒に調べてくれた後輩くんありがとう!
ではまた!