ASP.NET Core版 対人対戦できるぷよぷよをつくる(5)の続きです。

これまでは対戦して終わったらなにもしませんでした。勝ち数を記憶させてランクアップを競うようにすれば面白さも倍増するかもしれません。その前提として他のプレイヤーの足を引っ張るために同じ名前でプレイしてわざと負けてランクを下げるようなインチキができないように、プレイヤーの同一性を区別できるようにしておかなければなりません。

ではどうすればいいでしょうか? ログイン機能を追加してログイン状態でプレイすればなりすましは防げるはずです。そこで今回は準備編として簡単なログイン機能を追加する方法を考えます。

簡単なログイン機能を実装する

まずProgram.csを編集します。プロジェクトを作成したときに生成されるProgram.csに以下の3行を追加します。

Program.cs

cshtmlファイル

次にcshtmlファイルとcsファイルを作成します。LoginTest名前空間のなかにFirstModelクラスを定義します。このクラスはPageModelクラスを継承しています。

cshtmlファイルはPagesフォルダの配下であればどこでもかまいません。最初はテキストボックスに文字列を入力してボタンをクリックすればログインできてしまう単純なものをつくります。パスワードを入力しないとログインできないものはそのあと考えます。

Pages\First.cshtml

csファイル

インデントが深くなるので名前空間は省略します。

Pages\First.cshtmlの最初に @model LoginTest.FirstModel と書いてあるのでページにアクセスするとOnGetメソッドが呼び出されます。このなかですでにログインしている場合はどのアカウント名でログインしているか、ログインしていない場合は”ログインしていません”と表示させます。

パスワードを入力しないとログインできなくする

次にパスワードを入力しないとログインできないように作りかえます。この場合、アカウント名とパスワードをどこかに保存しなければなりません。本当はMySQLのようなデータベースに保存するべきなのですが、ここでは単純にパスワードを入力しないとログインできないようにしたいだけなので、テキストファイルに保存します。ただしパスワードが流出するのは絶対に避けないといけないので暗号化された状態で保存します。

cshtmlファイル

ユーザーがログインしていないときはアカウント自体を作っていないかもしれません。そこでログインのためのフォームだけでなくユーザー登録をするためのフォームもいっしょに表示させます。そのうえでログインしているときはユーザー登録のためのフォームは明らかに不要なので非表示にします。

Pages\Second.cshtml

csファイル

次にcsファイル部分ですが同様に名前空間部分は省略します。

ログインユーザー名の取得

GetLoginPlayerNameメソッドはログインしているときにユーザー名を返します。ログインしていないときは空文字列を返します。

ユーザー登録されているかの確認

GetHashValueメソッドはパスワードをハッシュ値に変換します。ハッシュ化は基本的に不可逆変換であり、元に戻すことができません。そのためデータの流出が起きたときにも解読される心配がありません。そのためセキュリティレベルを引き上げることができるのです。

IsRegisteredメソッドはユーザー登録されているかどうかを調べます。

後述しますが、ユーザー名とパスワードのハッシュ値はテキストファイルにタブ区切りで保存されています。引数が2つあるメソッドはテキストファイルの行のなかにユーザー名があるかどうかを調べるだけでなく、パスワードのハッシュ値を生成してこれが保存されているものと一致するかどうかを調べます。ユーザー名がみつかってもパスワードのハッシュ値が異なっていればログインしようとした人が正しくないパスワードを入力したと判断できます。

引数が1つしかないものはテキストファイルの行のなかにユーザー名があるかどうかだけ調べます。これによってすでに同じユーザー名で登録することを不可能にしています。

ユーザー登録するための処理

ユーザー登録するための処理を示します。

パスワードは見えないので入力ミスを防ぐため、2回入力させます。そして異なっている場合はユーザー登録できないことにします。

[登録]ボタンがクリックされたら登録しようとしているユーザー名がInputRegisterNameに、パスワードがPassword1とPassword2に格納されます。これらに文字列が格納されているか、Password1とPassword2は同じかを確認したらユーザー名からタブ文字を取り除きます(データを保存するときタブ区切りにするため)。

そのあとIsRegisteredメソッドで同じユーザー名で登録されていないか調べます。もし重複がなければユーザー登録の処理をおこないます。GetHashValueメソッドでパスワードのハッシュ値を生成してサーバー上のファイルに書き込みます。

いずれの場合もユーザー登録の処理が成功したのかどうかわかるように、処理結果をRegisterResultTextに格納してページに表示させます。

ログインするための処理

ログインしていないならログインの処理をおこないます。ユーザーがアカウント名とパスワードとして入力した文字列がInputPlayerNameとPasswordに格納されているので、サーバー上のファイルのなかにInputPlayerNameからタブ文字を取り除いたものとパスワードのハッシュ値が書き込まれた行がないか調べます。あればログインの処理をおこないます。なければ入力ミスか悪意を持つ者によるアクセスなので、ログインできない旨を表示させます。

すでにログインされている場合はログアウトの処理をおこないます。