Scala
Play
PlayFramework
Play2
Hatena

Playframeworkではてなの認証してみた

More than 3 years have passed since last update.
playhatenaauth.scala
package controllers

import play.api._
import play.api.libs.ws.WS
import play.api.mvc._
import play.api.Play.current
import scala.concurrent.Await

object Application extends Controller {
  val hatenaApiKey = "XXXXXX"
  val hatenaSecretKey = "XXXXX"
  val hatenaCallbackUrl = "http://localhost:9000/hatena/redirect"

  def index = Action {
    Ok(views.html.index(hatenaUrl))
  }

  def hatenaRedirectReceiver(cert: String) = Action {
    val requestAuthUrl = "http://auth.hatena.ne.jp/api/auth.json"

    val params = Map("api_key" -> hatenaApiKey, "cert" -> cert, "api_sig" -> buildSignature(Some(cert)))
    val url = requestAuthUrl + params.map(p => p._1 + "=" + p._2).mkString("?", "&", "")
    import scala.concurrent.duration._
    Ok(Await.result(WS.url(url).get, 10.second).json)
  }

  private def hatenaUrl = {
    val sig = buildSignature()
    val url = s"http://auth.hatena.ne.jp/auth?api_key=${hatenaApiKey}&api_sig=${sig}"
    Logger.info(s"はてなにリクエストするurl request_url:${url}")
    url
  }

  private def buildSignature(cert: Option[String] = None): String = {
    cert match {
      case Some(c) =>
        val hashedPassword = s"${hatenaSecretKey + "api_key" + hatenaApiKey + "cert" + c}"
        encrypt(hashedPassword)

      case None =>
        val hashedPassword = s"${hatenaSecretKey + "api_key" + hatenaApiKey}"
        encrypt(hashedPassword)
    }
  }

  private def encrypt(code: String): String = {
    import java.security.MessageDigest
    val digestedBytes = MessageDigest.getInstance("MD5").digest(code.getBytes)
    digestedBytes.map("%02x".format(_)).mkString
  }
}