Play 2 Scala

Sample Project

Download this sample project configured with your Auth0 API Keys.

System Requirements
  • Scala 2.11.7
  • Typesafe Activator 1.3.7
  • Play framework 2.4.6
Show requirements

Add your Auth0 Configuration Keys

Add the client ID, client secret, domain, and callback URL for your application to application.conf. You can get your client ID, client secret, and domain from your application settings.

Add Your Auth0 Callback Handler

Add the handler for the Auth0 callback so you can authenticate the user and retrieve their information:

// controllers/Callback.scala
package controllers

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future

import play.api.Play
import play.api.Play.current
import play.api.cache.Cache
import play.api.http.HeaderNames
import play.api.http.MimeTypes
import play.api.libs.json.JsValue
import play.api.libs.json.Json
import play.api.libs.json.Json.toJsFieldJsValueWrapper
import play.api.libs.ws.WS
import play.api.mvc.Action
import play.api.mvc.Controller

class Callback extends Controller {

  // callback route
  def callback(codeOpt: Option[String] = None) = Action.async {
    (for {
      code <- codeOpt
    } yield {
      // Get the token
      getToken(code).flatMap { case (idToken, accessToken) =>
       // Get the user
       getUser(accessToken).map { user =>
          // Cache the user and tokens into cache and session respectively
          Cache.set(idToken+ "profile", user)
          Redirect(routes.User.index())
            .withSession(
              "idToken" -> idToken,
              "accessToken" -> accessToken
            )
      }

      }.recover {
        case ex: IllegalStateException => Unauthorized(ex.getMessage)
      }
    }).getOrElse(Future.successful(BadRequest("No parameters supplied")))
  }

  def getToken(code: String): Future[(String, String)] = {
    val tokenResponse = WS.url(String.format("https://%s/oauth/token", "YOUR_AUTH0_DOMAIN"))(Play.current).
      withHeaders(HeaderNames.ACCEPT -> MimeTypes.JSON).
      post(
        Json.obj(
          "client_id" -> "YOUR_CLIENT_ID",
          "client_secret" -> "YOUR_CLIENT_SECRET",
          "redirect_uri" -> "http://localhost:9000/callback",
          "code" -> code,
          "grant_type"-> "authorization_code"
        )
      )

    tokenResponse.flatMap { response =>
      (for {
        idToken <- (response.json \ "id_token").asOpt[String]
        accessToken <- (response.json \ "access_token").asOpt[String]
      } yield {
        Future.successful((idToken, accessToken))
      }).getOrElse(Future.failed[(String, String)](new IllegalStateException("Tokens not sent")))
    }

  }

  def getUser(accessToken: String): Future[JsValue] = {
    val userResponse = WS.url(String.format("https://%s/userinfo", "YOUR_AUTH0_DOMAIN"))(Play.current)
      .withQueryString("access_token" -> accessToken)
      .get()

    userResponse.flatMap(response => Future.successful(response.json))
  }
}

For security purposes, you must add the callback URL of your app to your Client Settings.

Your callback URL is currently set to:

https://YOUR_APP/callback

Your callback URL should look something like:

https://yourapp.com/callback

Trigger Login Manually or Integrate Lock

For more information on using Lock see the documentation.

<script src="https://cdn.auth0.com/js/lock/10.6/lock.min.js"></script>
<script>
  var lock = new Auth0Lock('YOUR_CLIENT_ID', 'YOUR_AUTH0_DOMAIN', {
    auth: {
      redirectUrl: 'https://YOUR_APP/callback',
      responseType: 'code',
      params: {
        scope: 'openid email' // Learn about scopes: https://auth0.com/docs/scopes
      }
    }
  });
</script>
<button onclick="lock.show();">Login</button>
<div id="root" style="width: 320px; margin: 40px auto; padding: 10px; border-style: dashed; border-width: 1px; box-sizing: border-box;">
    embedded area
</div>
<script src="https://cdn.auth0.com/js/lock/10.6/lock.min.js"></script>
<script>
  var lock = new Auth0Lock('YOUR_CLIENT_ID', 'YOUR_AUTH0_DOMAIN', {
    container: 'root',
    auth: {
      redirectUrl: 'https://YOUR_APP/callback',
      responseType: 'code',
      params: {
        scope: 'openid email' // Learn about scopes: https://auth0.com/docs/scopes
      }
    }
  });
  lock.show();
</script>
<script src="https://cdn.auth0.com/js/lock-passwordless-2.2.min.js"></script>
<script>
  var lock = new Auth0LockPasswordless('YOUR_CLIENT_ID', 'YOUR_AUTH0_DOMAIN');
  function open() {
    lock.sms({
      callbackURL: 'https://YOUR_APP/callback',
      authParams: {
        scope: 'openid email' // Learn about scopes: https://auth0.com/docs/scopes
      }
    });
  }
</script>
<button onclick="window.open();">SMS</button>
<script src="https://cdn.auth0.com/js/lock-passwordless-2.2.min.js"></script>
<script>
  var lock = new Auth0LockPasswordless('YOUR_CLIENT_ID', 'YOUR_AUTH0_DOMAIN');
  function open() {
    lock.emailcode({
      callbackURL: 'https://YOUR_APP/callback',
      authParams: {
        scope: 'openid email'  // Learn about scopes: https://auth0.com/docs/scopes
      }
    });
  }
</script>
<button onclick="window.open();">Email Code</button>
<button class="signin-google">Sign in with Google (redirect)</button><br>
<button class="signin-google-popup">Sign in with Google (popup)</button><br>
<br><p>--- or ---</p>
<label>Email</label><input type="text" id="email"><br>
<label>Password</label><input type="password" id="password"><br>
<button class="signin-db">Sign in with Email/Password</button>

<script src="https://cdn.auth0.com/w2/auth0-7.1.min.js"></script>
<script src="http://code.jquery.com/jquery.js"></script>
<script>
  var auth0 = new Auth0({
    domain:         'YOUR_AUTH0_DOMAIN',
    clientID:       'YOUR_CLIENT_ID',
    callbackURL:    'https://YOUR_APP/callback'
  });
  // sign-in with social provider with plain redirect
  $('.signin-google').on('click', function() {
    auth0.signin({connection: 'google-oauth2'}); // use connection identifier
  });
  // sign-in with social provider using a popup (window.open)
  $('.signin-google-popup').on('click', function() {
    auth0.signin({popup: true, connection: 'google-oauth2'},
                function(err, profile, id_token, access_token, state) {
                    /*
                      store the profile and id_token in a cookie or local storage
                        $.cookie('profile', profile);
                        $.cookie('id_token', id_token);
                    */
                });
  });
  $('.signin-db').on('click', function() {
    auth0.signin({
      connection: 'foo',
      username: 'bar',
      password: 'foobar'
    },
    function (err, profile, id_token, access_token, state) {
      /*
          store the profile and id_token in a cookie or local storage
            $.cookie('profile', profile);
            $.cookie('id_token', id_token);
        */
    });
  });
</script>

Note: The redirectUrl specified in the Auth0Lock constructor must match the callback URL specified in the previous step.

Access User Information

You can access the user information from the cache

// controllers/User.scala
package controllers

import play.api._
import play.api.mvc._
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import play.api.http.{MimeTypes, HeaderNames}
import play.api.libs.ws.WS
import play.api.mvc.{Results, Action, Controller}
import play.api.libs.json._
import play.api.cache.Cache
import play.api.Play.current
import play.mvc.Results.Redirect

class User extends Controller {
    def AuthenticatedAction(f: Request[AnyContent] => Result): Action[AnyContent] = {
      Action { request =>
        (request.session.get("idToken").flatMap { idToken =>
          Cache.getAs[JsValue](idToken + "profile")
        } map { profile =>
          f(request)
        }).orElse {
          Some(Redirect(controllers.routes.Application.index()))
        }.get
      }
    }

    def index = AuthenticatedAction { request =>
      val idToken = request.session.get("idToken").get
      val profile = Cache.getAs[JsValue](idToken + "profile").get
      Ok(views.html.user(profile))
    }
}
// views/user.html.scala
@(profile: JsValue)

@main("Auth0 Play2 Scala Sample","home") {
  <img class="avatar" src='@((profile \ "picture").as[String])'/>
  <h2>Welcome @((profile \ "name").as[String])</h2>
}

Optional Steps

You can add the following Action to check if the user is authenticated. If not, redirect them to the login page:

def AuthenticatedAction(f: Request[AnyContent] => Result): Action[AnyContent] = {
  Action { request =>
    (request.session.get("idToken").flatMap { idToken =>
      Cache.getAs[JsValue](idToken + "profile")
    } map { profile =>
      f(request)
    }).orElse {
      Some(Redirect(routes.Application.index()))
    }.get
  }
}

def index = AuthenticatedAction { request =>
  val idToken = request.session.get("idToken").get
  val profile = Cache.getAs[JsValue](idToken + "profile").get
  Ok(views.html.user(profile))
}
Use Auth0 for FREECreate free Account