2017-03-28 2 views
1

Je me débrouillais très bien ce matin quand j'ai réalisé que la connexion facebook ne fonctionnait plus dans mon application. Comme je l'ai mentionné, j'utilise le cadre de jeu avec silhouette version 2.0-RC1.Impossible de se connecter avec Facebook avec cadre de jeu, silhouette et satellite

C'est le problème:

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

Le problème est que la réponse JSON pour l'authentification n'a pas le format correct comme OAuth2Info attend, ce qui est bizarre parce que nous touchons jamais le mécanisme d'authentification et I » Je suis inquiet parce que cela pourrait être un problème de version de bibliothèque et la mise à jour de la silhouette n'est pas une option en ce moment ... Est-ce que quelqu'un a ce problème et a trouvé la solution? S'il vous plaît aidez-moi avec ce gars ... Merci beaucoup.

Répondre

0

Nous devons créer une implémentation personnalisée de FacebookProvider afin de traiter la nouvelle réponse de Facebook. Ici, il est

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 
    } 
}