文件

§Play 中的 OpenID 支援

OpenID 是讓使用者使用單一帳戶存取多項服務的協定。身為網頁開發人員,你可以使用 OpenID 提供使用者一種使用他們既有帳戶登入的方式,例如他們的 Google 帳戶。在企業中,你可能會使用 OpenID 連線到公司的 SSO 伺服器。

§簡而言之的 OpenID 流程

  1. 使用者提供他的 OpenID (一個 URL) 給你。
  2. 你的伺服器檢查 URL 背後的内容,以產生一個需要將使用者重新導向的 URL。
  3. 使用者在 OpenID 提供者上確認授權,並被重新導向回你的伺服器。
  4. 你的伺服器從該重新導向接收資訊,並向提供者確認資訊正確無誤。

如果你的所有使用者都使用相同的 OpenID 提供者 (例如,如果你決定完全依賴 Google 帳戶),則可以省略步驟 1。

§用法

若要使用 OpenID,請先將 openId 新增到你的 build.sbt 檔案

libraryDependencies ++= Seq(
  openId
)

現在,任何想要使用 OpenID 的控制器或元件都必須宣告對 OpenIdClient 的依賴關係

import javax.inject.Inject

import scala.concurrent.ExecutionContext
import scala.concurrent.Future

import play.api._
import play.api.data._
import play.api.data.Forms._
import play.api.libs.openid._
import play.api.mvc._

class IdController @Inject() (val openIdClient: OpenIdClient, c: ControllerComponents)(
    implicit val ec: ExecutionContext
) extends AbstractController(c)

我們已將 OpenIdClient 執行個體命名為 openIdClient,以下所有範例都將假設此名稱。

§OpenID in Play

OpenID API 具有兩個重要功能

如果 Future 失敗,您可以定義備援,將使用者重新導向回登入頁面或傳回 BadRequest

以下是一個使用範例(來自控制器)

def login = Action {
  Ok(views.html.login())
}

def loginPost = Action.async { implicit request =>
  Form(
    single(
      "openid" -> nonEmptyText
    )
  ).bindFromRequest()
    .fold(
      { error =>
        logger.info(s"bad request ${error.toString}")
        Future.successful(BadRequest(error.toString))
      },
      { openId =>
        openIdClient
          .redirectURL(openId, routes.Application.openIdCallback.absoluteURL())
          .map(url => Redirect(url))
          .recover { case t: Throwable => Redirect(routes.Application.login) }
      }
    )
}

def openIdCallback = Action.async { implicit request: Request[AnyContent] =>
  openIdClient
    .verifiedId(request)
    .map(info => Ok(info.id + "\n" + info.attributes))
    .recover {
      case t: Throwable =>
        // Here you should look at the error, and give feedback to the user
        Redirect(routes.Application.login)
    }
}

§延伸屬性

使用者的 OpenID 提供其身分。此通訊協定也支援取得 延伸屬性,例如電子郵件地址、名字或姓氏。

您可以從 OpenID 伺服器要求選用屬性及/或必要屬性。要求必要屬性表示如果使用者未提供這些屬性,他便無法登入您的服務。

延伸屬性會在重新導向 URL 中要求

openIdClient.redirectURL(
  openId,
  routes.Application.openIdCallback.absoluteURL(),
  Seq("email" -> "http://schema.openid.net/contact/email")
)

屬性將會在 OpenID 伺服器提供的 UserInfo 中提供。

下一步:存取受 OAuth 保護的資源


在此文件發現錯誤?此頁面的原始程式碼可以在 這裡 找到。在閱讀 文件指南 後,請隨時提出拉取請求。有問題或建議要分享?請前往 我們的社群論壇 與社群展開對話。