SlideShare a Scribd company logo
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
あんた誰?あんた誰?あんた誰?あんた誰?あんた誰?
☆ 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ヶ月使って挫折
☆ 今日はその挫折の話をしようと思います☆ 今日はその挫折の話をしようと思います☆ 今日はその挫折の話をしようと思います☆ 今日はその挫折の話をしようと思います☆ 今日はその挫折の話をしようと思います
Playを使ってみようという話にPlayを使ってみようという話にPlayを使ってみようという話にPlayを使ってみようという話にPlayを使ってみようという話に
☆ 某案件でWebフレームワークを選定☆ 某案件でWebフレームワークを選定☆ 某案件でWebフレームワークを選定☆ 某案件でWebフレームワークを選定☆ 某案件でWebフレームワークを選定
☆ なにはともあれ型の強い言語を使いたい☆ なにはともあれ型の強い言語を使いたい☆ なにはともあれ型の強い言語を使いたい☆ なにはともあれ型の強い言語を使いたい☆ なにはともあれ型の強い言語を使いたい
☆ まずはScala+Playをさわってみよう☆ まずはScala+Playをさわってみよう☆ まずはScala+Playをさわってみよう☆ まずはScala+Playをさわってみよう☆ まずはScala+Playをさわってみよう
どーせならSlick使おうどーせならSlick使おうどーせならSlick使おうどーせならSlick使おうどーせならSlick使おう
☆ 次期PlayではSlickが標準サポートに☆ 次期PlayではSlickが標準サポートに☆ 次期PlayではSlickが標準サポートに☆ 次期PlayではSlickが標準サポートに☆ 次期PlayではSlickが標準サポートに
☆ それ以上Slickについて良く知らなかった☆ それ以上Slickについて良く知らなかった☆ それ以上Slickについて良く知らなかった☆ それ以上Slickについて良く知らなかった☆ それ以上Slickについて良く知らなかった
認証は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はマニュアルがわかりやすい
build.sbtbuild.sbtbuild.sbtbuild.sbtbuild.sbt
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"
)
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"
)
conf/application.confconf/application.confconf/application.confconf/application.confconf/application.conf
db.default.driver=org.h2.Driver
db.default.url="jdbc:h2:mem:play"
db.default.user=sa
db.default.password=""
slick.default="models.*"
db.default.driver=org.h2.Driver
db.default.url="jdbc:h2:mem:play"
db.default.user=sa
db.default.password=""
slick.default="models.*"
db.default.driver=org.h2.Driver
db.default.url="jdbc:h2:mem:play"
db.default.user=sa
db.default.password=""
slick.default="models.*"
db.default.driver=org.h2.Driver
db.default.url="jdbc:h2:mem:play"
db.default.user=sa
db.default.password=""
slick.default="models.*"
db.default.driver=org.h2.Driver
db.default.url="jdbc:h2:mem:play"
db.default.user=sa
db.default.password=""
slick.default="models.*"
conf/routesconf/routesconf/routesconf/routesconf/routes
# Home page
GET / controllers.Application.login
POST /login controllers.Application.authenticate
GET /logout controllers.Application.logout
# Home page
GET / controllers.Application.login
POST /login controllers.Application.authenticate
GET /logout controllers.Application.logout
# Home page
GET / controllers.Application.login
POST /login controllers.Application.authenticate
GET /logout controllers.Application.logout
# Home page
GET / controllers.Application.login
POST /login controllers.Application.authenticate
GET /logout controllers.Application.logout
# Home page
GET / controllers.Application.login
POST /login controllers.Application.authenticate
GET /logout controllers.Application.logout
app/models/Account.scala #1app/models/Account.scala #1app/models/Account.scala #1app/models/Account.scala #1app/models/Account.scala #1
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))
}
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))
}
app/models/Account.scala #2app/models/Account.scala #2app/models/Account.scala #2app/models/Account.scala #2app/models/Account.scala #2
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)
}
}
// 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) {
}
}
app/models/Role.scalaapp/models/Role.scalaapp/models/Role.scalaapp/models/Role.scalaapp/models/Role.scala
package models
sealed trait Role
case object Administrator extends Role
case 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 Role
case object Administrator extends Role
case 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 Role
case object Administrator extends Role
case 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 Role
case object Administrator extends Role
case 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 Role
case object Administrator extends Role
case object NormalUser extends Role
object Role {
def valueOf(value: String): Role = value match {
case "Administrator" => Administrator
case "NormalUser" => NormalUser
case _ => throw new IllegalArgumentException()
}
}
app/Global.scalaapp/Global.scalaapp/Global.scalaapp/Global.scalaapp/Global.scala
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
}
}
}
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
}
}
}
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.scala
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.defaultContext
import 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.defaultContext
import 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.defaultContext
import 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.defaultContext
import 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.defaultContext
import scala.reflect._
Application.scala #2Application.scala #2Application.scala #2Application.scala #2Application.scala #2
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 = 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
Application.scala #3Application.scala #3Application.scala #3Application.scala #3Application.scala #3
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 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))
さっそく起動してみるさっそく起動してみるさっそく起動してみるさっそく起動してみるさっそく起動してみる
$ ./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
データベース初期化データベース初期化データベース初期化データベース初期化データベース初期化
ログイン画面ログイン画面ログイン画面ログイン画面ログイン画面
でもこれ認証してなくね?でもこれ認証してなくね?でもこれ認証してなくね?でもこれ認証してなくね?でもこれ認証してなくね?
☆ 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使わない方が楽?
@gakuzzzzさんのアドバイス@gakuzzzzさんのアドバイス@gakuzzzzさんのアドバイス@gakuzzzzさんのアドバイス@gakuzzzzさんのアドバイス

More Related Content

What's hot

Advanced jQuery
Advanced jQueryAdvanced jQuery
Advanced jQuery
sergioafp
 
Let jQuery Rock Your World
Let jQuery Rock Your WorldLet jQuery Rock Your World
Let jQuery Rock Your World
Matt Gifford
 
An Introduction to Jquery
An Introduction to JqueryAn Introduction to Jquery
An Introduction to Jquery
Phil Reither
 
SQLAlchemy Seminar
SQLAlchemy SeminarSQLAlchemy Seminar
SQLAlchemy Seminar
Yury Yurevich
 
Automatically Spotting Cross-language Relations
Automatically Spotting Cross-language RelationsAutomatically Spotting Cross-language Relations
Automatically Spotting Cross-language Relations
Federico Tomassetti
 
Taking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order FunctionsTaking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order Functions
David Golden
 
Idioms in swift 2016 05c
Idioms in swift 2016 05cIdioms in swift 2016 05c
Idioms in swift 2016 05c
Kaz Yoshikawa
 
Dip Your Toes In The Sea Of Security (PHPNW16)
Dip Your Toes In The Sea Of Security (PHPNW16)Dip Your Toes In The Sea Of Security (PHPNW16)
Dip Your Toes In The Sea Of Security (PHPNW16)
James Titcumb
 
[ WrocLoveRb 2012] user perspective testing using ruby
[ WrocLoveRb 2012] user perspective testing using ruby[ WrocLoveRb 2012] user perspective testing using ruby
[ WrocLoveRb 2012] user perspective testing using ruby
Mikstura.IT Foundation | Web & Mobile Community
 
持续集成中心:新时代的软件研发管理体系
持续集成中心:新时代的软件研发管理体系持续集成中心:新时代的软件研发管理体系
持续集成中心:新时代的软件研发管理体系gigix1980
 
SQL Injection Part 2
SQL Injection Part 2SQL Injection Part 2
SQL Injection Part 2
n|u - The Open Security Community
 
jQuery Basic API
jQuery Basic APIjQuery Basic API
jQuery Basic API
Hyeonseok Shin
 
Dip Your Toes in the Sea of Security
Dip Your Toes in the Sea of SecurityDip Your Toes in the Sea of Security
Dip Your Toes in the Sea of Security
James Titcumb
 
Datamapper @ Railsconf2010
Datamapper @ Railsconf2010Datamapper @ Railsconf2010
Datamapper @ Railsconf2010
Dirkjan Bussink
 
Symfony day 2016
Symfony day 2016Symfony day 2016
Symfony day 2016
Samuele Lilli
 
Intro to OAuth
Intro to OAuthIntro to OAuth
Intro to OAuth
mfrost503
 
Chasing Bugs with the BeepBeep Event Stream Processor
Chasing Bugs with the BeepBeep Event Stream ProcessorChasing Bugs with the BeepBeep Event Stream Processor
Chasing Bugs with the BeepBeep Event Stream Processor
Sylvain Hallé
 
How to actually use promises - Jakob Mattsson, FishBrain
How to actually use promises - Jakob Mattsson, FishBrainHow to actually use promises - Jakob Mattsson, FishBrain
How to actually use promises - Jakob Mattsson, FishBrain
Codemotion Tel Aviv
 
Climbing the Abstract Syntax Tree (PHP South Africa 2017)
Climbing the Abstract Syntax Tree (PHP South Africa 2017)Climbing the Abstract Syntax Tree (PHP South Africa 2017)
Climbing the Abstract Syntax Tree (PHP South Africa 2017)
James Titcumb
 

What's hot (20)

Advanced jQuery
Advanced jQueryAdvanced jQuery
Advanced jQuery
 
Let jQuery Rock Your World
Let jQuery Rock Your WorldLet jQuery Rock Your World
Let jQuery Rock Your World
 
An Introduction to Jquery
An Introduction to JqueryAn Introduction to Jquery
An Introduction to Jquery
 
SQLAlchemy Seminar
SQLAlchemy SeminarSQLAlchemy Seminar
SQLAlchemy Seminar
 
Automatically Spotting Cross-language Relations
Automatically Spotting Cross-language RelationsAutomatically Spotting Cross-language Relations
Automatically Spotting Cross-language Relations
 
Taking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order FunctionsTaking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order Functions
 
Idioms in swift 2016 05c
Idioms in swift 2016 05cIdioms in swift 2016 05c
Idioms in swift 2016 05c
 
Dip Your Toes In The Sea Of Security (PHPNW16)
Dip Your Toes In The Sea Of Security (PHPNW16)Dip Your Toes In The Sea Of Security (PHPNW16)
Dip Your Toes In The Sea Of Security (PHPNW16)
 
[ WrocLoveRb 2012] user perspective testing using ruby
[ WrocLoveRb 2012] user perspective testing using ruby[ WrocLoveRb 2012] user perspective testing using ruby
[ WrocLoveRb 2012] user perspective testing using ruby
 
[ HackFest.pl 2012] Testing - what for and how
[ HackFest.pl 2012] Testing - what for and how[ HackFest.pl 2012] Testing - what for and how
[ HackFest.pl 2012] Testing - what for and how
 
持续集成中心:新时代的软件研发管理体系
持续集成中心:新时代的软件研发管理体系持续集成中心:新时代的软件研发管理体系
持续集成中心:新时代的软件研发管理体系
 
SQL Injection Part 2
SQL Injection Part 2SQL Injection Part 2
SQL Injection Part 2
 
jQuery Basic API
jQuery Basic APIjQuery Basic API
jQuery Basic API
 
Dip Your Toes in the Sea of Security
Dip Your Toes in the Sea of SecurityDip Your Toes in the Sea of Security
Dip Your Toes in the Sea of Security
 
Datamapper @ Railsconf2010
Datamapper @ Railsconf2010Datamapper @ Railsconf2010
Datamapper @ Railsconf2010
 
Symfony day 2016
Symfony day 2016Symfony day 2016
Symfony day 2016
 
Intro to OAuth
Intro to OAuthIntro to OAuth
Intro to OAuth
 
Chasing Bugs with the BeepBeep Event Stream Processor
Chasing Bugs with the BeepBeep Event Stream ProcessorChasing Bugs with the BeepBeep Event Stream Processor
Chasing Bugs with the BeepBeep Event Stream Processor
 
How to actually use promises - Jakob Mattsson, FishBrain
How to actually use promises - Jakob Mattsson, FishBrainHow to actually use promises - Jakob Mattsson, FishBrain
How to actually use promises - Jakob Mattsson, FishBrain
 
Climbing the Abstract Syntax Tree (PHP South Africa 2017)
Climbing the Abstract Syntax Tree (PHP South Africa 2017)Climbing the Abstract Syntax Tree (PHP South Africa 2017)
Climbing the Abstract Syntax Tree (PHP South Africa 2017)
 

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

Functional Principles for OO Developers
Functional Principles for OO DevelopersFunctional Principles for OO Developers
Functional Principles for OO Developers
jessitron
 
Php Code Audits (PHP UK 2010)
Php Code Audits (PHP UK 2010)Php Code Audits (PHP UK 2010)
Php Code Audits (PHP UK 2010)Damien Seguy
 
MySQLConf2009: Taking ActiveRecord to the Next Level
MySQLConf2009: Taking ActiveRecord to the Next LevelMySQLConf2009: Taking ActiveRecord to the Next Level
MySQLConf2009: Taking ActiveRecord to the Next Level
Blythe Dunham
 
Web Security - Hands-on
Web Security - Hands-onWeb Security - Hands-on
Web Security - Hands-on
Andrea Valenza
 
Symfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsSymfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsIgnacio Martín
 
Page Caching Resurrected
Page Caching ResurrectedPage Caching Resurrected
Page Caching Resurrected
Ben Scofield
 
Quick ref capybara
Quick ref capybaraQuick ref capybara
Quick ref capybara
fatec
 
Quick ref capybara
Quick ref capybaraQuick ref capybara
Quick ref capybara
fatec
 
Django O/R Mapper
Django O/R MapperDjango O/R Mapper
Django O/R Mapper
Ian Lewis
 
JavaScript and the AST
JavaScript and the ASTJavaScript and the AST
JavaScript and the AST
Jarrod Overson
 
Proposed PHP function: is_literal()
Proposed PHP function: is_literal()Proposed PHP function: is_literal()
Proposed PHP function: is_literal()
Craig Francis
 
Dip Your Toes in the Sea of Security (CoderCruise 2017)
Dip Your Toes in the Sea of Security (CoderCruise 2017)Dip Your Toes in the Sea of Security (CoderCruise 2017)
Dip Your Toes in the Sea of Security (CoderCruise 2017)
James Titcumb
 
GCRC 2014 - The Dark Side of Ruby
GCRC 2014 - The Dark Side of RubyGCRC 2014 - The Dark Side of Ruby
GCRC 2014 - The Dark Side of Ruby
Gautam Rege
 
Great Developers Steal
Great Developers StealGreat Developers Steal
Great Developers Steal
Ben Scofield
 
Dip Your Toes in the Sea of Security (IPC Fall 2017)
Dip Your Toes in the Sea of Security (IPC Fall 2017)Dip Your Toes in the Sea of Security (IPC Fall 2017)
Dip Your Toes in the Sea of Security (IPC Fall 2017)
James Titcumb
 
Webauthn Tutorial
Webauthn TutorialWebauthn Tutorial
Webauthn Tutorial
FIDO Alliance
 
User Behavior Tracking with Google Analytics, Garb, and Vanity
User Behavior Tracking with Google Analytics, Garb, and VanityUser Behavior Tracking with Google Analytics, Garb, and Vanity
User Behavior Tracking with Google Analytics, Garb, and Vanity
Tony Pitale
 
SummaryHW6 Account ManagementIn HW4, you kept track of multiple.pdf
SummaryHW6 Account ManagementIn HW4, you kept track of multiple.pdfSummaryHW6 Account ManagementIn HW4, you kept track of multiple.pdf
SummaryHW6 Account ManagementIn HW4, you kept track of multiple.pdf
ARORACOCKERY2111
 
Dip Your Toes in the Sea of Security (PHP South Africa 2017)
Dip Your Toes in the Sea of Security (PHP South Africa 2017)Dip Your Toes in the Sea of Security (PHP South Africa 2017)
Dip Your Toes in the Sea of Security (PHP South Africa 2017)
James Titcumb
 
Concern of Web Application Security
Concern of Web Application SecurityConcern of Web Application Security
Concern of Web Application Security
Mahmud Ahsan
 

Similar to Play, Slick, play2-authの間で討死 (20)

Functional Principles for OO Developers
Functional Principles for OO DevelopersFunctional Principles for OO Developers
Functional Principles for OO Developers
 
Php Code Audits (PHP UK 2010)
Php Code Audits (PHP UK 2010)Php Code Audits (PHP UK 2010)
Php Code Audits (PHP UK 2010)
 
MySQLConf2009: Taking ActiveRecord to the Next Level
MySQLConf2009: Taking ActiveRecord to the Next LevelMySQLConf2009: Taking ActiveRecord to the Next Level
MySQLConf2009: Taking ActiveRecord to the Next Level
 
Web Security - Hands-on
Web Security - Hands-onWeb Security - Hands-on
Web Security - Hands-on
 
Symfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsSymfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worlds
 
Page Caching Resurrected
Page Caching ResurrectedPage Caching Resurrected
Page Caching Resurrected
 
Quick ref capybara
Quick ref capybaraQuick ref capybara
Quick ref capybara
 
Quick ref capybara
Quick ref capybaraQuick ref capybara
Quick ref capybara
 
Django O/R Mapper
Django O/R MapperDjango O/R Mapper
Django O/R Mapper
 
JavaScript and the AST
JavaScript and the ASTJavaScript and the AST
JavaScript and the AST
 
Proposed PHP function: is_literal()
Proposed PHP function: is_literal()Proposed PHP function: is_literal()
Proposed PHP function: is_literal()
 
Dip Your Toes in the Sea of Security (CoderCruise 2017)
Dip Your Toes in the Sea of Security (CoderCruise 2017)Dip Your Toes in the Sea of Security (CoderCruise 2017)
Dip Your Toes in the Sea of Security (CoderCruise 2017)
 
GCRC 2014 - The Dark Side of Ruby
GCRC 2014 - The Dark Side of RubyGCRC 2014 - The Dark Side of Ruby
GCRC 2014 - The Dark Side of Ruby
 
Great Developers Steal
Great Developers StealGreat Developers Steal
Great Developers Steal
 
Dip Your Toes in the Sea of Security (IPC Fall 2017)
Dip Your Toes in the Sea of Security (IPC Fall 2017)Dip Your Toes in the Sea of Security (IPC Fall 2017)
Dip Your Toes in the Sea of Security (IPC Fall 2017)
 
Webauthn Tutorial
Webauthn TutorialWebauthn Tutorial
Webauthn Tutorial
 
User Behavior Tracking with Google Analytics, Garb, and Vanity
User Behavior Tracking with Google Analytics, Garb, and VanityUser Behavior Tracking with Google Analytics, Garb, and Vanity
User Behavior Tracking with Google Analytics, Garb, and Vanity
 
SummaryHW6 Account ManagementIn HW4, you kept track of multiple.pdf
SummaryHW6 Account ManagementIn HW4, you kept track of multiple.pdfSummaryHW6 Account ManagementIn HW4, you kept track of multiple.pdf
SummaryHW6 Account ManagementIn HW4, you kept track of multiple.pdf
 
Dip Your Toes in the Sea of Security (PHP South Africa 2017)
Dip Your Toes in the Sea of Security (PHP South Africa 2017)Dip Your Toes in the Sea of Security (PHP South Africa 2017)
Dip Your Toes in the Sea of Security (PHP South Africa 2017)
 
Concern of Web Application Security
Concern of Web Application SecurityConcern of Web Application Security
Concern of Web Application Security
 

Recently uploaded

Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
Guy Korland
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
Aftab Hussain
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptxSecstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
nkrafacyberclub
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
Alpen-Adria-Universität
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
Matthew Sinclair
 
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AIEnchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Vladimir Iglovikov, Ph.D.
 
Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1
DianaGray10
 
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
Neo4j
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
KatiaHIMEUR1
 
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex ProofszkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
Alex Pruden
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...
sonjaschweigert1
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
Octavian Nadolu
 
Large Language Model (LLM) and it’s Geospatial Applications
Large Language Model (LLM) and it’s Geospatial ApplicationsLarge Language Model (LLM) and it’s Geospatial Applications
Large Language Model (LLM) and it’s Geospatial Applications
Rohit Gautam
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
Pierluigi Pugliese
 
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
SOFTTECHHUB
 
Microsoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdfMicrosoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdf
Uni Systems S.M.S.A.
 
GridMate - End to end testing is a critical piece to ensure quality and avoid...
GridMate - End to end testing is a critical piece to ensure quality and avoid...GridMate - End to end testing is a critical piece to ensure quality and avoid...
GridMate - End to end testing is a critical piece to ensure quality and avoid...
ThomasParaiso2
 

Recently uploaded (20)

Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptxSecstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
 
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AIEnchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
 
Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1
 
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
 
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex ProofszkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
 
Large Language Model (LLM) and it’s Geospatial Applications
Large Language Model (LLM) and it’s Geospatial ApplicationsLarge Language Model (LLM) and it’s Geospatial Applications
Large Language Model (LLM) and it’s Geospatial Applications
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
 
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
 
Microsoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdfMicrosoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdf
 
GridMate - End to end testing is a critical piece to ensure quality and avoid...
GridMate - End to end testing is a critical piece to ensure quality and avoid...GridMate - End to end testing is a critical piece to ensure quality and avoid...
GridMate - End to end testing is a critical piece to ensure quality and avoid...
 

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

  • 1. 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
  • 2. あんた誰?あんた誰?あんた誰?あんた誰?あんた誰? ☆ 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ヶ月使って挫折 ☆ 今日はその挫折の話をしようと思います☆ 今日はその挫折の話をしようと思います☆ 今日はその挫折の話をしようと思います☆ 今日はその挫折の話をしようと思います☆ 今日はその挫折の話をしようと思います
  • 3. Playを使ってみようという話にPlayを使ってみようという話にPlayを使ってみようという話にPlayを使ってみようという話にPlayを使ってみようという話に ☆ 某案件でWebフレームワークを選定☆ 某案件でWebフレームワークを選定☆ 某案件でWebフレームワークを選定☆ 某案件でWebフレームワークを選定☆ 某案件でWebフレームワークを選定 ☆ なにはともあれ型の強い言語を使いたい☆ なにはともあれ型の強い言語を使いたい☆ なにはともあれ型の強い言語を使いたい☆ なにはともあれ型の強い言語を使いたい☆ なにはともあれ型の強い言語を使いたい ☆ まずはScala+Playをさわってみよう☆ まずはScala+Playをさわってみよう☆ まずはScala+Playをさわってみよう☆ まずはScala+Playをさわってみよう☆ まずはScala+Playをさわってみよう
  • 4. どーせならSlick使おうどーせならSlick使おうどーせならSlick使おうどーせならSlick使おうどーせならSlick使おう ☆ 次期PlayではSlickが標準サポートに☆ 次期PlayではSlickが標準サポートに☆ 次期PlayではSlickが標準サポートに☆ 次期PlayではSlickが標準サポートに☆ 次期PlayではSlickが標準サポートに ☆ それ以上Slickについて良く知らなかった☆ それ以上Slickについて良く知らなかった☆ それ以上Slickについて良く知らなかった☆ それ以上Slickについて良く知らなかった☆ それ以上Slickについて良く知らなかった
  • 5. 認証は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はマニュアルがわかりやすい
  • 6. build.sbtbuild.sbtbuild.sbtbuild.sbtbuild.sbt 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" ) 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" )
  • 8. conf/routesconf/routesconf/routesconf/routesconf/routes # Home page GET / controllers.Application.login POST /login controllers.Application.authenticate GET /logout controllers.Application.logout # Home page GET / controllers.Application.login POST /login controllers.Application.authenticate GET /logout controllers.Application.logout # Home page GET / controllers.Application.login POST /login controllers.Application.authenticate GET /logout controllers.Application.logout # Home page GET / controllers.Application.login POST /login controllers.Application.authenticate GET /logout controllers.Application.logout # Home page GET / controllers.Application.login POST /login controllers.Application.authenticate GET /logout controllers.Application.logout
  • 9. app/models/Account.scala #1app/models/Account.scala #1app/models/Account.scala #1app/models/Account.scala #1app/models/Account.scala #1 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)) } 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)) }
  • 10. app/models/Account.scala #2app/models/Account.scala #2app/models/Account.scala #2app/models/Account.scala #2app/models/Account.scala #2 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) } } // 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) { } }
  • 11. app/models/Role.scalaapp/models/Role.scalaapp/models/Role.scalaapp/models/Role.scalaapp/models/Role.scala package models sealed trait Role case object Administrator extends Role case 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 Role case object Administrator extends Role case 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 Role case object Administrator extends Role case 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 Role case object Administrator extends Role case 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 Role case object Administrator extends Role case object NormalUser extends Role object Role { def valueOf(value: String): Role = value match { case "Administrator" => Administrator case "NormalUser" => NormalUser case _ => throw new IllegalArgumentException() } }
  • 12. app/Global.scalaapp/Global.scalaapp/Global.scalaapp/Global.scalaapp/Global.scala 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 } } } 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 } } }
  • 13. 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.scala 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.defaultContext import 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.defaultContext import 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.defaultContext import 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.defaultContext import 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.defaultContext import scala.reflect._
  • 14. Application.scala #2Application.scala #2Application.scala #2Application.scala #2Application.scala #2 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 = 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
  • 15. Application.scala #3Application.scala #3Application.scala #3Application.scala #3Application.scala #3 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 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))
  • 16. さっそく起動してみるさっそく起動してみるさっそく起動してみるさっそく起動してみるさっそく起動してみる $ ./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
  • 19. でもこれ認証してなくね?でもこれ認証してなくね?でもこれ認証してなくね?でもこれ認証してなくね?でもこれ認証してなくね? ☆ 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使わない方が楽?