When creating a web application, you often want to register user information and restrict page access. This time, I implemented the authentication function using Play Framework. The source can be found on GitHub.
--Authentication by registering and collating user information --Access restrictions to the home screen (Next post) --Transfer of authentication authority when the same user as the authenticating user signs in from another browser (Next post)
--Sign-up screen --Sign-in screen
PlayAuthentication
├── app
│ ├── common
│ │ ├── global
│ │ │ └── AppActionCreator.java
│ │ └── secure
│ │ └── AppAuthenticator.java
│ ├── controllers
│ │ ├── AppController.java
│ │ ├── IndexController.java
│ │ ├── SigninController.java
│ │ └── SignupController.java
│ ├── forms
│ │ ├── AppForm.java
│ │ ├── SigninForm.java
│ │ └── SignupForm.java
│ ├── models
│ │ ├── AppModel.java
│ │ └── User.java
│ └── views
│ ├── index.scala.html
│ ├── main.scala.html
│ ├── signin.scala.html
│ └── signup.scala.html
├── build.sbt
├── conf
│ ├── application.conf
│ ├── evolutions
│ │ └── default
│ │ └── 1.sql
│ └── routes
└── project
└── plugins.sbt
I think that the file name somehow conveys the role.
Register the user information entered from the sign-up screen in the DB. On the sign-in screen, enter your e-mail address and password and verify with the DB information to authenticate. I would like to store the entered user information in the H2DB of the in-memory database. I would like to use Ebean, which is compatible with Play, for the O / R mapper, and Evolutions for database management. To use H2DB, Ebean, and Evolutions, modify the following three points and reload and update sbt.
build.sbt
lazy val root = (project in file(".")).enablePlugins(PlayJava, PlayEbean) //Added PlayEbean
libraryDependencies += evolutions //add to
project/plugins.sbt
addSbtPlugin("com.typesafe.sbt" % "sbt-play-ebean" % "3.0.0") //add to
conf/application.conf
db {
default.driver = org.h2.Driver
default.url="jdbc:h2:mem:play;MODE=MYSQL" #This time MySQL mode
default.username = sa
default.password = ""
}
ebean {
default = ["models.*"]
}
Then create a Java object Model class that holds the database information with the models package. I would like to create a superclass in the Model class and define the creation date and time and the last update date and time for all tables. This time, only the User table is created, so it doesn't make much sense.
AppModel.java
package models;
//import statement omitted
@MappedSuperclass
public abstract class AppModel extends Model {
/** ID */
@Id
public Long id;
/**Creation date and time*/
@CreatedTimestamp
public LocalDateTime created;
/**Last Modified*/
@UpdatedTimestamp
public LocalDateTime updated;
}
User.java
package models;
//import statement omitted
@Entity
public class User extends AppModel {
/**name*/
public String name;
/**mail address*/
public String email;
/**password*/
public String password;
/**Last login date and time*/
public LocalDateTime logined;
}
At this point, start the server and access it. Then you will see the following screen in your browser.
If you press the "Apply this script now!" Button as it is, SQL will be executed and a table will be created in H2DB. In addition, the following SQL files will be generated in conf / evolutions / default.
1.sql
# --- Created by Ebean DDL
# To stop Ebean DDL generation, remove this comment and start using Evolutions
# --- !Ups
create table user (
id bigint not null,
name varchar(255),
email varchar(255),
password varchar(255),
logined timestamp,
created timestamp not null,
updated timestamp not null,
constraint pk_user primary key (id)
);
create sequence user_seq;
# --- !Downs
drop table if exists user;
drop sequence if exists user_seq;
This seems to be raising the schema by looking at the Model class that is annotating the javax.persistence.Entity.
Now that we have confirmed that the database has been created, the next step is to create a screen for signing up and signing in. Create a View and Form respectively, and give the item an email address and password. I also gave the sign-up a name. This time, the source of View and Form is simple, so I will omit it. If you are interested, please refer to GitHub. Also, please refer to Post written about View and Form in Realization of vlidation function.
After that, the controller processes using the information input from the screen. The sign-up screen controller saves your name, email address, and password in the DB as user information.
SignupController.java
package controllers;
//import statement omitted
@Singleton
public class SignupController extends AppController {
@Inject
public SignupController(CacheApi cache) {
super(cache);
}
@Inject
private FormFactory formFactory;
@Override
public Result get() {
Form<SignupForm> form = formFactory.form(SignupForm.class);
return ok(views.html.signup.render(form));
}
@Override
public Result post() {
Form<SignupForm> form = formFactory.form(SignupForm.class).bindFromRequest();
if(form.hasErrors()){
return badRequest(views.html.signup.render(form));
}
try{
/*
*Register new user information.
*/
Ebean.beginTransaction();
User user = new User();
user.name = form.get().name;
user.email = form.get().email;
user.password = BCrypt.hashpw(form.get().password, BCrypt.gensalt());
user.logined = LocalDateTime.now();
Ebean.insert(user);
Ebean.commitTransaction();
new SigninController(cache).setCacheUser(user);
}catch(Exception e){
Ebean.rollbackTransaction();
return badRequest(views.html.signup.render(form));
}finally {
Ebean.endTransaction();
}
return redirect(routes.IndexController.get());
}
}
The sign-in screen controller updates the login date and time of the user with the entered email address.
SigninController.java
package controllers;
//import statement omitted
@Singleton
public class SigninController extends AppController {
@Inject
private FormFactory formFactory;
/**User information key*/
public static final String USER_KEY = "USER";
@Inject
public SigninController(CacheApi cache) {
super(cache);
}
@Override
public Result get() {
Form<SigninForm> form = formFactory.form(SigninForm.class);
return ok(views.html.signin.render(form));
}
@Override
public Result post() {
Form<SigninForm> form = formFactory.form(SigninForm.class).bindFromRequest();
if(form.hasErrors()){
return badRequest(views.html.signin.render(form));
}
try{
/*
*Update the user's login date and time.
*/
Ebean.beginTransaction();
User user = Ebean.find(User.class).where().eq("email", form.get().email).findUnique();
user.logined = LocalDateTime.now();
Ebean.update(user);
Ebean.commitTransaction();
setCacheUser(user);
}catch(Exception e){
Ebean.rollbackTransaction();
return badRequest(views.html.signin.render(form));
}finally {
Ebean.endTransaction();
}
return redirect(routes.IndexController.get());
}
/*
*The following methods are omitted
*/
}
When saving user information on the sign-up screen controller, BCrypt is used to hash the password.
build.sbt
libraryDependencies += "org.mindrot" % "jbcrypt" % "0.4" //add to
After writing, please relaod and update sbt again.
This time I wrote about the part necessary to register and collate user information. I felt that there were many parts that I found useful for database management and operation rather than authentication. Access restrictions not written this time are written in here. GitHub
Recommended Posts