2015-08-15 91 views
2

我已經採用與實施例玩剪影-角種子。 通過衛星授權可以正常工作。輪廓和移動應用

當我嘗試通過iOS應用授權我得到了一個錯誤:

com.mohiva.play.silhouette.impl.exceptions.UnexpectedResponseException: 
[Silhouette][facebook] Cannot build OAuth2Info because of invalid response format: 
List((/access_token,List(ValidationError(List(error.path.missing),WrappedArray())))) 

我在這個功能得到了一個錯誤400從OAuth2Provider.scala:

protected def getAccessToken(code: String)(implicit request: RequestHeader): Future[OAuth2Info] = { 
httpLayer.url(settings.accessTokenURL).withHeaders(headers: _*).post(Map(
    ClientID -> Seq(settings.clientID), 
    ClientSecret -> Seq(settings.clientSecret), 
    GrantType -> Seq(AuthorizationCode), 
    Code -> Seq(code), 
    RedirectURI -> Seq(resolveCallbackURL(settings.redirectURL))) ++ settings.accessTokenParams.mapValues(Seq(_))).flatMap { response => 
    logger.debug("[Silhouette][%s] Access token response: [%s]".format(id, response.body)) 
    Future.from(buildInfo(response)) 
} 

}

回答

1

這錯誤已經上升,因爲通過Facebook進行身份驗證的衛星發送給服務器一個「身份驗證代碼」,而Silhouette服務器使用此代碼獲取Facebook的「訪問令牌」並創建用戶。

的Facebook的iOS SDK,相反,獲得「訪問令牌」和我試着將它發送到服務器以JSON在外地「代碼」像「Satellizer。

要解決這個問題,我在一個名爲Json的現場發送的訪問令牌「ACCESS_TOKEN」,並使用下面的代碼來驗證移動應用程序:

class MobileSocialAuthController @Inject() (
    val messagesApi: MessagesApi, 
    userService: UserService, 
    authInfoRepository: AuthInfoRepository, 
    socialProviderRegistry: SocialProviderRegistry, 
    val env: Environment[User, JWTAuthenticator]) 
    extends Silhouette[User, JWTAuthenticator] 
{ 
    def authenticate(provider: String) = UserAwareAction.async(parse.json) { 
    implicit request => 
     provider match { 
     case "facebook" => 
      request.body.asOpt[OAuth2Info] match { 
      case Some(authInfo) => 
       (socialProviderRegistry.get[FacebookProvider](provider) match { 
       case Some(p: FacebookProvider) => 
        for { 
        profile <-p.retrieveProfile(authInfo) 
        user <- userService.save(profile) 
        authInfo <- authInfoRepository.save(profile.loginInfo, authInfo) 
        authenticator <- env.authenticatorService.create(profile.loginInfo) 
        token <- env.authenticatorService.init(authenticator) 
        } yield { 
        env.eventBus.publish(LoginEvent(user, request, request2Messages)) 
        Ok(Json.obj("token" -> token)) 
        } 
       case _ => Future.failed(new ProviderException(s"Cannot authenticate with unexpected social provider $provider")) 
       }).recover { 
       case e: ProviderException => 
        logger.error("Unexpected provider error", e) 
        Unauthorized(Json.obj("message" -> Messages("could.not.authenticate"))) 
       } 
      case _ => 
       Future(BadRequest(Json.obj(
       "message" -> "Bad OAuth2 json."))) 
      } 
     case _ => 
      Future(BadRequest(Json.obj(
      "message" -> "You can use only Facebook account for authentication."))) 
     } 
    } 
} 

其結果是,我有我在使用令牌ios應用程序獲取資源。

+0

我在嘗試使用您的解決方案時未收到'未授權'響應。你遇到過這個問題嗎? – crockpotveggies

0

發生這種情況時OAuth2Provider得到一個它無法解析的響應,也就是說,任何非成功的響應。因此,出現此錯誤的原因可能很多,例如授權碼無效或過期,或者您尚未正確配置redirect_uri(在Facebook開發站點上檢查您的Facebook應用程序配置以設置redirect_uri)。

剪影做記錄它從Facebook獲取響應這應有助於你調試的實際問題是什麼,日誌行尋找在您提供的片段:

logger.debug("[Silhouette][%s] Access token response:... 

因此,檢查你的日誌,還有你應該看到來自Facebook的迴應,可能會有一個錯誤,指出他們爲什麼不能給你一個access_token