Top Banner
Play, Slick, play2-authの間で討死 Play, Slick, play2-authの間で討死 Play, Slick, play2-authの間で討死 Play, Slick, play2-authの間で討死 Play, Slick, play2-authの間で討死 Kiwamu Okabe Kiwamu Okabe Kiwamu Okabe Kiwamu Okabe Kiwamu Okabe
20

Play, Slick, play2-authの間で討死

Jul 16, 2015

Download

Technology

Kiwamu Okabe
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Play, Slick, play2-authの間で討死

Play, Slick, play2-authの間で討死Play, Slick, play2-authの間で討死Play, Slick, play2-authの間で討死Play, Slick, play2-authの間で討死Play, Slick, play2-authの間で討死

Kiwamu OkabeKiwamu OkabeKiwamu OkabeKiwamu OkabeKiwamu Okabe

Page 2: Play, Slick, play2-authの間で討死

あんた誰?あんた誰?あんた誰?あんた誰?あんた誰?

☆ http://www.masterq.net/☆ http://www.masterq.net/☆ http://www.masterq.net/☆ http://www.masterq.net/☆ http://www.masterq.net/

☆ 名前: 岡部 究 (オカベ キワム)☆ 名前: 岡部 究 (オカベ キワム)☆ 名前: 岡部 究 (オカベ キワム)☆ 名前: 岡部 究 (オカベ キワム)☆ 名前: 岡部究 (オカベキワム)

☆ 元組み込みエンジニア☆ 元組み込みエンジニア☆ 元組み込みエンジニア☆ 元組み込みエンジニア☆ 元組み込みエンジニア

☆ Web関連技術初心者☆ Web関連技術初心者☆ Web関連技術初心者☆ Web関連技術初心者☆ Web関連技術初心者

☆ Scalaは1ヶ月使って挫折☆ Scalaは1ヶ月使って挫折☆ Scalaは1ヶ月使って挫折☆ Scalaは1ヶ月使って挫折☆ Scalaは1ヶ月使って挫折

☆ 今日はその挫折の話をしようと思います☆ 今日はその挫折の話をしようと思います☆ 今日はその挫折の話をしようと思います☆ 今日はその挫折の話をしようと思います☆ 今日はその挫折の話をしようと思います

Page 3: Play, Slick, play2-authの間で討死

Playを使ってみようという話にPlayを使ってみようという話にPlayを使ってみようという話にPlayを使ってみようという話にPlayを使ってみようという話に

☆ 某案件でWebフレームワークを選定☆ 某案件でWebフレームワークを選定☆ 某案件でWebフレームワークを選定☆ 某案件でWebフレームワークを選定☆ 某案件でWebフレームワークを選定

☆ なにはともあれ型の強い言語を使いたい☆ なにはともあれ型の強い言語を使いたい☆ なにはともあれ型の強い言語を使いたい☆ なにはともあれ型の強い言語を使いたい☆ なにはともあれ型の強い言語を使いたい

☆ まずはScala+Playをさわってみよう☆ まずはScala+Playをさわってみよう☆ まずはScala+Playをさわってみよう☆ まずはScala+Playをさわってみよう☆ まずはScala+Playをさわってみよう

Page 4: Play, Slick, play2-authの間で討死

どーせならSlick使おうどーせならSlick使おうどーせならSlick使おうどーせならSlick使おうどーせならSlick使おう

☆ 次期PlayではSlickが標準サポートに☆ 次期PlayではSlickが標準サポートに☆ 次期PlayではSlickが標準サポートに☆ 次期PlayではSlickが標準サポートに☆ 次期PlayではSlickが標準サポートに

☆ それ以上Slickについて良く知らなかった☆ それ以上Slickについて良く知らなかった☆ それ以上Slickについて良く知らなかった☆ それ以上Slickについて良く知らなかった☆ それ以上Slickについて良く知らなかった

Page 5: Play, Slick, play2-authの間で討死

認証はplay2-authを認証はplay2-authを認証はplay2-authを認証はplay2-authを認証はplay2-authを

☆ ユーザ/パスワード認証が欲しいだけだった☆ ユーザ/パスワード認証が欲しいだけだった☆ ユーザ/パスワード認証が欲しいだけだった☆ ユーザ/パスワード認証が欲しいだけだった☆ ユーザ/パスワード認証が欲しいだけだった

☆ SecureSocialはごっつい☆ SecureSocialはごっつい☆ SecureSocialはごっつい☆ SecureSocialはごっつい☆ SecureSocialはごっつい

☆ play2-authはマニュアルがわかりやすい☆ play2-authはマニュアルがわかりやすい☆ play2-authはマニュアルがわかりやすい☆ play2-authはマニュアルがわかりやすい☆ play2-authはマニュアルがわかりやすい

Page 6: Play, Slick, play2-authの間で討死

build.sbtbuild.sbtbuild.sbtbuild.sbtbuild.sbtlibraryDependencies ++= Seq( jdbc, anorm, cache, ws, "mysql" % "mysql-connector-java" % "5.1.34", "com.typesafe.play" %% "play-slick" % "0.8.1", "jp.t2v" %% "play2-auth" % "0.13.0", "jp.t2v" %% "play2-auth-test" % "0.13.0" % "test", "jp.t2v" %% "stackable-controller" % "0.4.1")

libraryDependencies ++= Seq( jdbc, anorm, cache, ws, "mysql" % "mysql-connector-java" % "5.1.34", "com.typesafe.play" %% "play-slick" % "0.8.1", "jp.t2v" %% "play2-auth" % "0.13.0", "jp.t2v" %% "play2-auth-test" % "0.13.0" % "test", "jp.t2v" %% "stackable-controller" % "0.4.1")

libraryDependencies ++= Seq( jdbc, anorm, cache, ws, "mysql" % "mysql-connector-java" % "5.1.34", "com.typesafe.play" %% "play-slick" % "0.8.1", "jp.t2v" %% "play2-auth" % "0.13.0", "jp.t2v" %% "play2-auth-test" % "0.13.0" % "test", "jp.t2v" %% "stackable-controller" % "0.4.1")

libraryDependencies ++= Seq( jdbc, anorm, cache, ws, "mysql" % "mysql-connector-java" % "5.1.34", "com.typesafe.play" %% "play-slick" % "0.8.1", "jp.t2v" %% "play2-auth" % "0.13.0", "jp.t2v" %% "play2-auth-test" % "0.13.0" % "test", "jp.t2v" %% "stackable-controller" % "0.4.1")

libraryDependencies ++= Seq( jdbc, anorm, cache, ws, "mysql" % "mysql-connector-java" % "5.1.34", "com.typesafe.play" %% "play-slick" % "0.8.1", "jp.t2v" %% "play2-auth" % "0.13.0", "jp.t2v" %% "play2-auth-test" % "0.13.0" % "test", "jp.t2v" %% "stackable-controller" % "0.4.1")

Page 7: Play, Slick, play2-authの間で討死

conf/application.confconf/application.confconf/application.confconf/application.confconf/application.confdb.default.driver=org.h2.Driverdb.default.url="jdbc:h2:mem:play"db.default.user=sadb.default.password=""

slick.default="models.*"

db.default.driver=org.h2.Driverdb.default.url="jdbc:h2:mem:play"db.default.user=sadb.default.password=""

slick.default="models.*"

db.default.driver=org.h2.Driverdb.default.url="jdbc:h2:mem:play"db.default.user=sadb.default.password=""

slick.default="models.*"

db.default.driver=org.h2.Driverdb.default.url="jdbc:h2:mem:play"db.default.user=sadb.default.password=""

slick.default="models.*"

db.default.driver=org.h2.Driverdb.default.url="jdbc:h2:mem:play"db.default.user=sadb.default.password=""

slick.default="models.*"

Page 8: Play, Slick, play2-authの間で討死

conf/routesconf/routesconf/routesconf/routesconf/routes# Home pageGET / controllers.Application.loginPOST /login controllers.Application.authenticateGET /logout controllers.Application.logout

# Home pageGET / controllers.Application.loginPOST /login controllers.Application.authenticateGET /logout controllers.Application.logout

# Home pageGET / controllers.Application.loginPOST /login controllers.Application.authenticateGET /logout controllers.Application.logout

# Home pageGET / controllers.Application.loginPOST /login controllers.Application.authenticateGET /logout controllers.Application.logout

# Home pageGET / controllers.Application.loginPOST /login controllers.Application.authenticateGET /logout controllers.Application.logout

Page 9: Play, Slick, play2-authの間で討死

app/models/Account.scala #1app/models/Account.scala #1app/models/Account.scala #1app/models/Account.scala #1app/models/Account.scala #1package models

import play.api.db.slick.Config.driver.simple._

case class Account(station_id: String, member_id: String, password: String)

class Accounts(tag: Tag) extends Table[Account](tag, "ACCOUNT") { def station_id = column[String]("STATION_ID") def member_id = column[String]("MEMBER_ID") def password = column[String]("PASSWORD") def * = (station_id, member_id, password) <> (Account.tupled, Account.unapply _) def pk = primaryKey("pk_a", (station_id, member_id))}

package models

import play.api.db.slick.Config.driver.simple._

case class Account(station_id: String, member_id: String, password: String)

class Accounts(tag: Tag) extends Table[Account](tag, "ACCOUNT") { def station_id = column[String]("STATION_ID") def member_id = column[String]("MEMBER_ID") def password = column[String]("PASSWORD") def * = (station_id, member_id, password) <> (Account.tupled, Account.unapply _) def pk = primaryKey("pk_a", (station_id, member_id))}

package models

import play.api.db.slick.Config.driver.simple._

case class Account(station_id: String, member_id: String, password: String)

class Accounts(tag: Tag) extends Table[Account](tag, "ACCOUNT") { def station_id = column[String]("STATION_ID") def member_id = column[String]("MEMBER_ID") def password = column[String]("PASSWORD") def * = (station_id, member_id, password) <> (Account.tupled, Account.unapply _) def pk = primaryKey("pk_a", (station_id, member_id))}

package models

import play.api.db.slick.Config.driver.simple._

case class Account(station_id: String, member_id: String, password: String)

class Accounts(tag: Tag) extends Table[Account](tag, "ACCOUNT") { def station_id = column[String]("STATION_ID") def member_id = column[String]("MEMBER_ID") def password = column[String]("PASSWORD") def * = (station_id, member_id, password) <> (Account.tupled, Account.unapply _) def pk = primaryKey("pk_a", (station_id, member_id))}

package models

import play.api.db.slick.Config.driver.simple._

case class Account(station_id: String, member_id: String, password: String)

class Accounts(tag: Tag) extends Table[Account](tag, "ACCOUNT") {def station_id = column[String]("STATION_ID")def member_id = column[String]("MEMBER_ID")def password = column[String]("PASSWORD")def * = (station_id, member_id, password) <> (Account.tupled,

Account.unapply _)def pk = primaryKey("pk_a", (station_id, member_id))

}

Page 10: Play, Slick, play2-authの間で討死

app/models/Account.scala #2app/models/Account.scala #2app/models/Account.scala #2app/models/Account.scala #2app/models/Account.scala #2object Accounts { val account = TableQuery[Accounts]

def authenticate(sid: String, mid: String, password: String): Option[Account] = { findById((sid, mid)).filter { account => password.equals(account.password) } }

// xxx def findById(smid: (String, String)): Option[Account] = None // xxx def findAll(): Seq[Account] = Seq.empty // xxx def create(account: Account) { }}

object Accounts { val account = TableQuery[Accounts]

def authenticate(sid: String, mid: String, password: String): Option[Account] = { findById((sid, mid)).filter { account => password.equals(account.password) } }

// xxx def findById(smid: (String, String)): Option[Account] = None // xxx def findAll(): Seq[Account] = Seq.empty // xxx def create(account: Account) { }}

object Accounts { val account = TableQuery[Accounts]

def authenticate(sid: String, mid: String, password: String): Option[Account] = { findById((sid, mid)).filter { account => password.equals(account.password) } }

// xxx def findById(smid: (String, String)): Option[Account] = None // xxx def findAll(): Seq[Account] = Seq.empty // xxx def create(account: Account) { }}

object Accounts { val account = TableQuery[Accounts]

def authenticate(sid: String, mid: String, password: String): Option[Account] = { findById((sid, mid)).filter { account => password.equals(account.password) } }

// xxx def findById(smid: (String, String)): Option[Account] = None // xxx def findAll(): Seq[Account] = Seq.empty // xxx def create(account: Account) { }}

object Accounts {val account = TableQuery[Accounts]

def authenticate(sid: String, mid: String, password: String): Option[Account] = {

findById((sid, mid)).filter { account => password.equals(account.password) } }

// xxxdef findById(smid: (String, String)): Option[Account] = None// xxxdef findAll(): Seq[Account] = Seq.empty// xxxdef create(account: Account) {

}}

Page 11: Play, Slick, play2-authの間で討死

app/models/Role.scalaapp/models/Role.scalaapp/models/Role.scalaapp/models/Role.scalaapp/models/Role.scalapackage models

sealed trait Rolecase object Administrator extends Rolecase object NormalUser extends Role

object Role { def valueOf(value: String): Role = value match { case "Administrator" => Administrator case "NormalUser" => NormalUser case _ => throw new IllegalArgumentException() }}

package models

sealed trait Rolecase object Administrator extends Rolecase object NormalUser extends Role

object Role { def valueOf(value: String): Role = value match { case "Administrator" => Administrator case "NormalUser" => NormalUser case _ => throw new IllegalArgumentException() }}

package models

sealed trait Rolecase object Administrator extends Rolecase object NormalUser extends Role

object Role { def valueOf(value: String): Role = value match { case "Administrator" => Administrator case "NormalUser" => NormalUser case _ => throw new IllegalArgumentException() }}

package models

sealed trait Rolecase object Administrator extends Rolecase object NormalUser extends Role

object Role { def valueOf(value: String): Role = value match { case "Administrator" => Administrator case "NormalUser" => NormalUser case _ => throw new IllegalArgumentException() }}

package models

sealed trait Rolecase object Administrator extends Rolecase object NormalUser extends Role

object Role {def valueOf(value: String): Role = value match {case "Administrator" => Administratorcase "NormalUser" => NormalUsercase _ => throw new IllegalArgumentException()

}}

Page 12: Play, Slick, play2-authの間で討死

app/Global.scalaapp/Global.scalaapp/Global.scalaapp/Global.scalaapp/Global.scalaimport play.api._import models._

object Global extends GlobalSettings { override def onStart(app: Application) { if (Accounts.findAll.isEmpty) { Seq( Account("100001", "100001", "1") ) foreach Accounts.create } }}

import play.api._import models._

object Global extends GlobalSettings { override def onStart(app: Application) { if (Accounts.findAll.isEmpty) { Seq( Account("100001", "100001", "1") ) foreach Accounts.create } }}

import play.api._import models._

object Global extends GlobalSettings { override def onStart(app: Application) { if (Accounts.findAll.isEmpty) { Seq( Account("100001", "100001", "1") ) foreach Accounts.create } }}

import play.api._import models._

object Global extends GlobalSettings { override def onStart(app: Application) { if (Accounts.findAll.isEmpty) { Seq( Account("100001", "100001", "1") ) foreach Accounts.create } }}

import play.api._import models._

object Global extends GlobalSettings {override def onStart(app: Application) {if (Accounts.findAll.isEmpty) {

Seq(Account("100001", "100001", "1")

) foreach Accounts.create } }}

Page 13: Play, Slick, play2-authの間で討死

Application.scala #1Application.scala #1Application.scala #1Application.scala #1Application.scala #1

app/controllers/Application.scalaapp/controllers/Application.scalaapp/controllers/Application.scalaapp/controllers/Application.scalaapp/controllers/Application.scalapackage controllers

import jp.t2v.lab.play2.auth._import models._import play.api._import play.api.data._import play.api.data.Forms._import play.api.mvc._import play.api.mvc.Results._

import scala.concurrent.{Future, ExecutionContext}import play.api.libs.concurrent.Execution.Implicits.defaultContextimport scala.reflect._

package controllers

import jp.t2v.lab.play2.auth._import models._import play.api._import play.api.data._import play.api.data.Forms._import play.api.mvc._import play.api.mvc.Results._

import scala.concurrent.{Future, ExecutionContext}import play.api.libs.concurrent.Execution.Implicits.defaultContextimport scala.reflect._

package controllers

import jp.t2v.lab.play2.auth._import models._import play.api._import play.api.data._import play.api.data.Forms._import play.api.mvc._import play.api.mvc.Results._

import scala.concurrent.{Future, ExecutionContext}import play.api.libs.concurrent.Execution.Implicits.defaultContextimport scala.reflect._

package controllers

import jp.t2v.lab.play2.auth._import models._import play.api._import play.api.data._import play.api.data.Forms._import play.api.mvc._import play.api.mvc.Results._

import scala.concurrent.{Future, ExecutionContext}import play.api.libs.concurrent.Execution.Implicits.defaultContextimport scala.reflect._

package controllers

import jp.t2v.lab.play2.auth._import models._import play.api._import play.api.data._import play.api.data.Forms._import play.api.mvc._import play.api.mvc.Results._

import scala.concurrent.{Future, ExecutionContext}import play.api.libs.concurrent.Execution.Implicits.defaultContextimport scala.reflect._

Page 14: Play, Slick, play2-authの間で討死

Application.scala #2Application.scala #2Application.scala #2Application.scala #2Application.scala #2trait AuthConfigImpl extends AuthConfig { type Id = (String, String) type User = Account val idTag: ClassTag[Id] = classTag[Id] val sessionTimeoutInSeconds: Int = 3600

def resolveUser(id: Id)(implicit ctx: ExecutionContext): Future[Option[User]] = Future.successful(Accounts.findById(id)) def loginSucceeded(request: RequestHeader)(implicit ctx: ExecutionContext): Future[Result] = Future.successful(Redirect(routes.Application.login)) def logoutSucceeded(request: RequestHeader)(implicit ctx: ExecutionContext): Future[Result] = Future.successful(Redirect(routes.Application.login)) def authenticationFailed(request: RequestHeader)(implicit ctx: ExecutionContext): Future[Result] = Future.successful(Redirect(routes.Application.login)) def authorizationFailed(request: RequestHeader)(implicit ctx: ExecutionContext): Future[Result] = Future.successful(Forbidden("no permission")) def authorize(user: User, authority: Authority)(implicit ctx: ExecutionContext): Future[Boolean] = Future.successful(false) // xxx}

trait AuthConfigImpl extends AuthConfig { type Id = (String, String) type User = Account val idTag: ClassTag[Id] = classTag[Id] val sessionTimeoutInSeconds: Int = 3600

def resolveUser(id: Id)(implicit ctx: ExecutionContext): Future[Option[User]] = Future.successful(Accounts.findById(id)) def loginSucceeded(request: RequestHeader)(implicit ctx: ExecutionContext): Future[Result] = Future.successful(Redirect(routes.Application.login)) def logoutSucceeded(request: RequestHeader)(implicit ctx: ExecutionContext): Future[Result] = Future.successful(Redirect(routes.Application.login)) def authenticationFailed(request: RequestHeader)(implicit ctx: ExecutionContext): Future[Result] = Future.successful(Redirect(routes.Application.login)) def authorizationFailed(request: RequestHeader)(implicit ctx: ExecutionContext): Future[Result] = Future.successful(Forbidden("no permission")) def authorize(user: User, authority: Authority)(implicit ctx: ExecutionContext): Future[Boolean] = Future.successful(false) // xxx}

trait AuthConfigImpl extends AuthConfig { type Id = (String, String) type User = Account val idTag: ClassTag[Id] = classTag[Id] val sessionTimeoutInSeconds: Int = 3600

def resolveUser(id: Id)(implicit ctx: ExecutionContext): Future[Option[User]] = Future.successful(Accounts.findById(id)) def loginSucceeded(request: RequestHeader)(implicit ctx: ExecutionContext): Future[Result] = Future.successful(Redirect(routes.Application.login)) def logoutSucceeded(request: RequestHeader)(implicit ctx: ExecutionContext): Future[Result] = Future.successful(Redirect(routes.Application.login)) def authenticationFailed(request: RequestHeader)(implicit ctx: ExecutionContext): Future[Result] = Future.successful(Redirect(routes.Application.login)) def authorizationFailed(request: RequestHeader)(implicit ctx: ExecutionContext): Future[Result] = Future.successful(Forbidden("no permission")) def authorize(user: User, authority: Authority)(implicit ctx: ExecutionContext): Future[Boolean] = Future.successful(false) // xxx}

trait AuthConfigImpl extends AuthConfig { type Id = (String, String) type User = Account val idTag: ClassTag[Id] = classTag[Id] val sessionTimeoutInSeconds: Int = 3600

def resolveUser(id: Id)(implicit ctx: ExecutionContext): Future[Option[User]] = Future.successful(Accounts.findById(id)) def loginSucceeded(request: RequestHeader)(implicit ctx: ExecutionContext): Future[Result] = Future.successful(Redirect(routes.Application.login)) def logoutSucceeded(request: RequestHeader)(implicit ctx: ExecutionContext): Future[Result] = Future.successful(Redirect(routes.Application.login)) def authenticationFailed(request: RequestHeader)(implicit ctx: ExecutionContext): Future[Result] = Future.successful(Redirect(routes.Application.login)) def authorizationFailed(request: RequestHeader)(implicit ctx: ExecutionContext): Future[Result] = Future.successful(Forbidden("no permission")) def authorize(user: User, authority: Authority)(implicit ctx: ExecutionContext): Future[Boolean] = Future.successful(false) // xxx}

trait AuthConfigImpl extends AuthConfig {type Id = (String, String)type User = Accountval idTag: ClassTag[Id] = classTag[Id]val sessionTimeoutInSeconds: Int = 3600

def resolveUser(id: Id)(implicit ctx: ExecutionContext): Future[Option[User]] = Future.successful(Accounts.findById(id))def loginSucceeded(request: RequestHeader)(implicit ctx:

ExecutionContext): Future[Result] = Future.successful(Redirect(routes.Application.login))def logoutSucceeded(request: RequestHeader)(implicit ctx:

ExecutionContext): Future[Result] = Future.successful(Redirect(routes.Application.login))def authenticationFailed(request: RequestHeader)(implicit ctx:

ExecutionContext): Future[Result] = Future.successful(Redirect(routes.Application.login))def authorizationFailed(request: RequestHeader)(implicit ctx:

ExecutionContext): Future[Result] = Future.successful(Forbidden("no permission"))def authorize(user: User, authority: Authority)(implicit ctx:

ExecutionContext): Future[Boolean] = Future.successful(false) // xxx}

Page 15: Play, Slick, play2-authの間で討死

Application.scala #3Application.scala #3Application.scala #3Application.scala #3Application.scala #3object Application extends Controller with LoginLogout with AuthConfigImpl { val loginForm = Form { mapping("station_id" -> text, "member_id" -> text, "password" -> text)(Accounts.authenticate)(_.map(u => (u.station_id, u.member_id, ""))) .verifying("Invalid email or password", result => result.isDefined) } def login = Action { implicit request => Ok(views.html.login(loginForm)) } def logout = Action.async { implicit request => gotoLogoutSucceeded.map(_.flashing( "success" -> "You've been logged out" )) } def authenticate = Action.async { implicit request => loginForm.bindFromRequest.fold( formWithErrors => Future.successful(BadRequest(views.html.login(formWithErrors))), user => gotoLoginSucceeded((user.get.station_id, user.get.member_id)) )

object Application extends Controller with LoginLogout with AuthConfigImpl { val loginForm = Form { mapping("station_id" -> text, "member_id" -> text, "password" -> text)(Accounts.authenticate)(_.map(u => (u.station_id, u.member_id, ""))) .verifying("Invalid email or password", result => result.isDefined) } def login = Action { implicit request => Ok(views.html.login(loginForm)) } def logout = Action.async { implicit request => gotoLogoutSucceeded.map(_.flashing( "success" -> "You've been logged out" )) } def authenticate = Action.async { implicit request => loginForm.bindFromRequest.fold( formWithErrors => Future.successful(BadRequest(views.html.login(formWithErrors))), user => gotoLoginSucceeded((user.get.station_id, user.get.member_id)) )

object Application extends Controller with LoginLogout with AuthConfigImpl { val loginForm = Form { mapping("station_id" -> text, "member_id" -> text, "password" -> text)(Accounts.authenticate)(_.map(u => (u.station_id, u.member_id, ""))) .verifying("Invalid email or password", result => result.isDefined) } def login = Action { implicit request => Ok(views.html.login(loginForm)) } def logout = Action.async { implicit request => gotoLogoutSucceeded.map(_.flashing( "success" -> "You've been logged out" )) } def authenticate = Action.async { implicit request => loginForm.bindFromRequest.fold( formWithErrors => Future.successful(BadRequest(views.html.login(formWithErrors))), user => gotoLoginSucceeded((user.get.station_id, user.get.member_id)) )

object Application extends Controller with LoginLogout with AuthConfigImpl { val loginForm = Form { mapping("station_id" -> text, "member_id" -> text, "password" -> text)(Accounts.authenticate)(_.map(u => (u.station_id, u.member_id, ""))) .verifying("Invalid email or password", result => result.isDefined) } def login = Action { implicit request => Ok(views.html.login(loginForm)) } def logout = Action.async { implicit request => gotoLogoutSucceeded.map(_.flashing( "success" -> "You've been logged out" )) } def authenticate = Action.async { implicit request => loginForm.bindFromRequest.fold( formWithErrors => Future.successful(BadRequest(views.html.login(formWithErrors))), user => gotoLoginSucceeded((user.get.station_id, user.get.member_id)) )

object Application extends Controller with LoginLogout withAuthConfigImpl {val loginForm = Form {mapping("station_id" -> text, "member_id" -> text, "password" -

> text)(Accounts.authenticate)(_.map(u => (u.station_id, u.member_id, ""))) .verifying("Invalid email or password", result => result.isDefined) }def login = Action { implicit request =>Ok(views.html.login(loginForm))

}def logout = Action.async { implicit request =>

gotoLogoutSucceeded.map(_.flashing("success" -> "You've been logged out"

)) }def authenticate = Action.async { implicit request =>

loginForm.bindFromRequest.fold( formWithErrors => Future.successful(BadRequest(views.html.login(formWithErrors))), user => gotoLoginSucceeded((user.get.station_id, user.get.member_id)) )

Page 16: Play, Slick, play2-authの間で討死

さっそく起動してみるさっそく起動してみるさっそく起動してみるさっそく起動してみるさっそく起動してみる$ ./activator run$ firefox localhost:9000$ ./activator run$ firefox localhost:9000$ ./activator run$ firefox localhost:9000$ ./activator run$ firefox localhost:9000$ ./activator run$ firefox localhost:9000

Page 17: Play, Slick, play2-authの間で討死

データベース初期化データベース初期化データベース初期化データベース初期化データベース初期化

Page 18: Play, Slick, play2-authの間で討死

ログイン画面ログイン画面ログイン画面ログイン画面ログイン画面

Page 19: Play, Slick, play2-authの間で討死

でもこれ認証してなくね?でもこれ認証してなくね?でもこれ認証してなくね?でもこれ認証してなくね?でもこれ認証してなくね?

☆ app/Global.scalaで作った100001ユーザですらログインできない☆ app/Global.scalaで作った100001ユーザですらログインできない☆ app/Global.scalaで作った100001ユーザですらログインできない☆ app/Global.scalaで作った100001ユーザですらログインできない☆ app/Global.scalaで作った100001ユーザですらログインできない

☆ Slickに全くさわってない☆ Slickに全くさわってない☆ Slickに全くさわってない☆ Slickに全くさわってない☆ Slickに全くさわってない

☆ play2-authのバックエンドにSlickを使うことは可能?☆ play2-authのバックエンドにSlickを使うことは可能?☆ play2-authのバックエンドにSlickを使うことは可能?☆ play2-authのバックエンドにSlickを使うことは可能?☆ play2-authのバックエンドにSlickを使うことは可能?

☆ もしくは1つのアプリケーションで複数のデータベースラッパーが混じるのはアリ?☆ もしくは1つのアプリケーションで複数のデータベースラッパーが混じるのはアリ?☆ もしくは1つのアプリケーションで複数のデータベースラッパーが混じるのはアリ?☆ もしくは1つのアプリケーションで複数のデータベースラッパーが混じるのはアリ?☆ もしくは1つのアプリケーションで複数のデータベースラッパーが混じるのはアリ?

☆ 実はSlick使わない方が楽?☆ 実はSlick使わない方が楽?☆ 実はSlick使わない方が楽?☆ 実はSlick使わない方が楽?☆ 実はSlick使わない方が楽?

Page 20: Play, Slick, play2-authの間で討死

@gakuzzzzさんのアドバイス@gakuzzzzさんのアドバイス@gakuzzzzさんのアドバイス@gakuzzzzさんのアドバイス@gakuzzzzさんのアドバイス