§Play 中的 OpenID 支援
OpenID 是讓使用者使用單一帳戶存取多項服務的協定。身為網頁開發人員,你可以使用 OpenID 提供使用者一種使用他們既有帳戶登入的方式,例如他們的 Google 帳戶。在企業中,你可能會使用 OpenID 連線到公司的 SSO 伺服器。
§簡而言之的 OpenID 流程
- 使用者提供他的 OpenID (一個 URL) 給你。
- 你的伺服器檢查 URL 背後的内容,以產生一個需要將使用者重新導向的 URL。
- 使用者在 OpenID 提供者上確認授權,並被重新導向回你的伺服器。
- 你的伺服器從該重新導向接收資訊,並向提供者確認資訊正確無誤。
如果你的所有使用者都使用相同的 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 具有兩個重要功能
OpenIdClient.redirectURL
計算您應將使用者重新導向到的 URL。它涉及非同步擷取使用者的 OpenID 頁面,這就是它傳回Future[String]
的原因。如果 OpenID 無效,傳回的Future
將會失敗。OpenIdClient.verifiedId
需要RequestHeader
,並檢查它以建立使用者資訊,包括其已驗證的 OpenID。它將非同步呼叫 OpenID 伺服器以檢查資訊的真實性,傳回 UserInfo 的未來。如果資訊不正確,或伺服器檢查為 false(例如,如果重新導向 URL 已偽造),傳回的Future
將會失敗。
如果 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 保護的資源
在此文件發現錯誤?此頁面的原始程式碼可以在 這裡 找到。在閱讀 文件指南 後,請隨時提出拉取請求。有問題或建議要分享?請前往 我們的社群論壇 與社群展開對話。