Playframework 无法使用play framework、剪影和卫星导航器登录Facebook

Playframework 无法使用play framework、剪影和卫星导航器登录Facebook,playframework,satellizer,silhouette,Playframework,Satellizer,Silhouette,今天早上,当我意识到facebook登录在我的应用程序中不再有效时,我的表现还不错。正如我所提到的,我正在将play框架与剪影版本2.0-RC1一起使用 这就是问题所在: [Silhouette][facebook] Cannot build OAuth2Info because of invalid response format : {"access_token":"EAAE2YyQkAUUBANAfoUfhdG8jrRfJnhrgZCaZB5FsZAO1G5Jq0ITTfZA6coj4g

今天早上,当我意识到facebook登录在我的应用程序中不再有效时,我的表现还不错。正如我所提到的,我正在将play框架与剪影版本2.0-RC1一起使用

这就是问题所在:

[Silhouette][facebook] Cannot build OAuth2Info because of invalid response format  : {"access_token":"EAAE2YyQkAUUBANAfoUfhdG8jrRfJnhrgZCaZB5FsZAO1G5Jq0ITTfZA6coj4g0HuUC48JToHCnZCFx8r9Q3JZCulzt6SaEcRqKrxNealsBldH4dpzJpK4oeblZAmxjq9Rjzl2rO3IKPUwllWAv5vEz33cGc4XeqLSgZD","token_type":"bearer","expires_in":5183717}

问题是,用于身份验证的Json响应没有OAuth2Info所期望的正确格式,这很奇怪,因为我们从未接触过身份验证机制,我担心这可能是库版本问题,而更新剪影现在不是一个选项。。。是否有人遇到了这个问题并找到了解决方案?请帮我对付这些家伙。。。非常感谢。

为了处理新facebook的答案,我们必须创建FacebookProvider的自定义实现。给你

    import com.mohiva.play.silhouette.api.LoginInfo
    import com.mohiva.play.silhouette.api.exceptions.AuthenticationException
    import com.mohiva.play.silhouette.api.util.HTTPLayer
    import com.mohiva.play.silhouette.impl.exceptions.ProfileRetrievalException
    import com.mohiva.play.silhouette.impl.providers.OAuth2Provider._
    import com.mohiva.play.silhouette.impl.providers._
    import com.mohiva.play.silhouette.impl.providers.oauth2.{FacebookProfileBuilder, FacebookProvider}
    import com.mohiva.play.silhouette.impl.providers.oauth2.FacebookProvider._
    import play.api.libs.concurrent.Execution.Implicits._
    import play.api.libs.json.{ JsObject, JsValue }
    import play.api.libs.ws.WSResponse
    import play.api.libs.json._

    import scala.concurrent.Future
    import scala.util.{ Failure, Success, Try }

    /**
     * A Facebook OAuth2 Provider.
     *
     * @param httpLayer The HTTP layer implementation.
     * @param stateProvider The state provider implementation.
     * @param settings The provider settings.
     *
     * @see https://developers.facebook.com/tools/explorer
     * @see https://developers.facebook.com/docs/graph-api/reference/user
     * @see https://developers.facebook.com/docs/facebook-login/access-tokens
     */
    abstract class FacebookProvider(httpLayer: HTTPLayer, stateProvider: OAuth2StateProvider, settings: OAuth2Settings)
      extends OAuth2Provider(httpLayer, stateProvider, settings) {

      /**
       * The content type to parse a profile from.
       */
      type Content = JsValue

      /**
       * Gets the provider ID.
       *
       * @return The provider ID.
       */
      val id = ID

      /**
       * Defines the URLs that are needed to retrieve the profile data.
       */
      protected val urls = Map("api" -> API)

      /**
       * Builds the social profile.
       *
       * @param authInfo The auth info received from the provider.
       * @return On success the build social profile, otherwise a failure.
       */
      protected def buildProfile(authInfo: OAuth2Info): Future[Profile] = {
        httpLayer.url(urls("api").format(authInfo.accessToken)).get().flatMap { response =>
          val json = response.json
          (json \ "error").asOpt[JsObject] match {
            case Some(error) =>
              val errorMsg = (error \ "message").as[String]
              val errorType = (error \ "type").as[String]
              val errorCode = (error \ "code").as[Int]

              throw new ProfileRetrievalException(SpecifiedProfileError.format(id, errorMsg, errorType, errorCode))
            case _ => profileParser.parse(json)
          }
        }
      }

      /**
       * Builds the OAuth2 info from response.
       *
       * @param response The response from the provider.
       * @return The OAuth2 info on success, otherwise a failure.
       */
      override def buildInfo(response: WSResponse): Try[OAuth2Info] = {
        val responseJson = Json.parse(response.body)
        responseJson.validate[OAuth2Info].asEither.fold(
          error => Failure(new AuthenticationException(InvalidInfoFormat.format(id, error))),
          info => Success(info)
        )
      }
    }

    /**
     * The profile parser for the common social profile.
     */
    class FacebookProfileParser extends SocialProfileParser[JsValue, CommonSocialProfile] {

      /**
       * Parses the social profile.
       *
       * @param json The content returned from the provider.
       * @return The social profile from given result.
       */
      def parse(json: JsValue) = Future.successful {
        val userID = (json \ "id").as[String]
        val firstName = (json \ "first_name").asOpt[String]
        val lastName = (json \ "last_name").asOpt[String]
        val fullName = (json \ "name").asOpt[String]
        val avatarURL = (json \ "picture" \ "data" \ "url").asOpt[String]
        val email = (json \ "email").asOpt[String]

        CommonSocialProfile(
          loginInfo = LoginInfo(ID, userID),
          firstName = firstName,
          lastName = lastName,
          fullName = fullName,
          avatarURL = avatarURL,
          email = email)
      }
    }

    /**
     * The profile builder for the common social profile.
     */
    trait FacebookProfileBuilder extends CommonSocialProfileBuilder {
      self: FacebookProvider =>

      /**
       * The profile parser implementation.
       */
      val profileParser = new FacebookProfileParser
    }

    /**
     * The companion object.
     */
    object FacebookWesuraProvider {

      /**
       * The error messages.
       */
      val SpecifiedProfileError = "[Silhouette][%s] Error retrieving profile information. Error message: %s, type: %s, code: %s"

      /**
       * The Facebook constants.
       */
      val ID = "facebook"
      val API = "https://graph.facebook.com/me?fields=name,first_name,last_name,picture,email&return_ssl_resources=1&access_token=%s"

      /**
       * Creates an instance of the provider.
       *
       * @param httpLayer The HTTP layer implementation.
       * @param stateProvider The state provider implementation.
       * @param settings The provider settings.
       * @return An instance of this provider.
       */
      def apply(httpLayer: HTTPL

ayer, stateProvider: OAuth2StateProvider, settings: OAuth2Settings) = {
    new FacebookProvider(httpLayer, stateProvider, settings) with FacebookProfileBuilder
  }
}

你有完整解决方案的公共回购协议吗?