Play Framework で作る簡易認証システム(その1: アカウント登録)

今回はPlay Framework で簡易認証システムを作っていく。
ログインした人だけ、つまりアカウントを持つ人だけにチャットの内容を見せるような仕組みを作りたいわけである。
何はともあれ、アカウント情報を保持するテーブルが必要だ。

1. アカウント情報テーブルの作成
models 以下に下記の通り、User.javaを作成しよう。アカウント情報として、id(自動採番), username(アカウント名), mail(メールアドレス), image(画像), password(パスワード)を持つようにする。

package models;

import javax.persistence.*;

import play.db.ebean.*;
import play.data.validation.Constraints.*;

@Entity
public class User extends Model {
	@Id
	public Long id;

	@Required
	public String username;

	@Email
	public String mail;

	public String image;

	@Required
	public String password;

	public static Finder<Long, User> find =
			new Finder<Long, User>(Long.class, User.class);

	@Override
	public String toString(){
		return ("[id:" + id + ", username:" + username + ", mail:" + mail +
				", tel:" + tel + "]");
	}

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUserame(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
    public String getImage() {
        return image;
    }
}

2. ユーザ情報登録機能画面の開発(View の作成)
ユーザ情報を登録する画面を作っていく。本画面にアクセスするパスは"/signup" とするにで、routesを下記の通りとする。

GET     /signup                     controllers.Application.signup()

続いて本URL"/signup"をリクエストされたときに呼び出されるコントローラsignupメソッドを実装する。

■Application.java

	public static Result signup(){
		//Userクラスの各フィールド(id, username, mail...)と同じ属性を持つFormオブジェクトを生成
		Form<User> userForm = new Form(User.class);
		
		return ok(signup.render("Sign up",userForm));
	}

ここで、ちょっとした小技を使っている。

		//Userクラスの各フィールド(id, username, mail...)と同じ属性を持つFormオブジェクトを生成
		Form<User> userForm = new Form(User.class);

userForm というFormクラスをインスタンス化したオブジェクトを作成するが、このときコンストラクタの引数として"User.class"を渡している。
どういう意味かというと、「User.classの持つフィールドを属性として持つForm オブジェクトを作成してね」という意味である。
以前フォームを利用したときに"PostChatForm"というフォームクラスを用意してから、
コントローラでフォームを作成したが、今回はフォームクラスを定義していない。
今回ユーザから求めるインプットは、アカウント名, メールアドレス, 画像, パスワードとなるが、これはUserクラスのフィールドと同じで、フォームの内容とテーブルの内容が1:1(※)で対応している。このようなとき、つまりフォームの内容をそのままテーブルに登録したいときにこの小技が使えるのだ。便利なので覚えておいて欲しいのだが、これはあくまでも小技なので、通常通りForm クラスを定義してから実装してもよい。
(※)厳密には1:1で対応しなくてもよいのだが、詳細は今後順次触れていくことにする。

return ok(signup.render("Sign up",userForm));
||>

続いて、上記メソッドで呼び出されるView の実装をしていく。

3. Viewの実装

■views/signup.scala.html
>|scala|
@(msg: String, userForm: Form[User])


@form(routes.Application.register, 'class -> "form-horizontal", 'enctype -> "multipart/form-data") {
	@inputText(form1("username"))
	@inputText(form1("mail"))
	@inputText(form1("password"))
    <button id="submit" type="submit" value="Submit" class="btn btn-primary">Sing up</button>
}

4. 登録用コントローラ(Application.render())の実装
上記フォームを投稿した際に呼びだされるApplication.render()メソッドを実装する。
まずは、忘れずにroutesに登録しておこう。

■routes

GET     /register                     controllers.Application.register()

続いてController(Application.register())を実装する。

■controllers/Application.java

	public static Result register(){

		//投稿されたフォームの内容をuserFormオブジェクトとしてインスタンス化
		Form<User> userForm = new Form(User.class).bindFromRequest();
		//もし、フォームの内容にエラーが無いようであれば
		if(!userForm.hasErrors()){
			//エンティティモデルであるUser オブジェクトにフォームの内容を登録する。
			User userRecd = userForm.get();
			//レコードの登録
			userRecd.save();
			return redirect("/inputchat");
		}else{
			return ok(signup.render("ERROR",userForm));
		}
	}


特に特異なことはしていない。
・素直にフォームから値を取得して、Formオブジェクト化

Form<User> userForm = new Form(User.class).bindFromRequest();

・Userオブジェクトをインスタス化してオブジェクトを保存する。

User userRecd = userForm.get();
//レコードの登録
userRecd.save();

これができたら、ここまでの動作を確認してみよう。ユーザ登録したあと、MySQLのWorkbench を起動してレコードが登録されているかどうか確認して欲しい。
http://localhost:9000/signup