剪影和移动应用程序
Posted
技术标签:
【中文标题】剪影和移动应用程序【英文标题】:Silhouette and mobile application 【发布时间】:2015-08-15 15:29:09 【问题描述】:我以 play-silhouette-angular-seed 为例。 通过 Satellizer 进行授权工作正常。
当我尝试通过 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()))))
我在 OAuth2Provider.scala 的这个函数中收到错误 400:
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 进行身份验证的 Satellizer 向服务器发送“身份验证代码”,而 Silhouette 服务器使用此代码获取 Facebook“访问令牌”并创建用户。
相反,Facebook iOs SDK 获得了“访问令牌”,我尝试将其发送到 Json 中的“代码”字段中的服务器,例如“卫星”。
为了解决这个问题,我在名为“access_token”的 Json 字段中发送了一个“访问令牌”,并使用下一个代码来验证移动应用程序:
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 应用程序中使用它来获取资源。
【讨论】:
我在尝试使用您的解决方案时收到未记录的Unauthorized
回复。您是否遇到过其他问题?【参考方案2】:
当OAuth2Provider
得到一个它无法解析的响应,即任何不成功的响应时,就会发生这种情况。所以这个错误可能有很多原因,例如授权码无效或过期,或者您没有正确配置redirect_uri(检查您在Facebook开发网站上的Facebook应用配置以设置redirect_uri)。
Silhouette 确实记录了它从 Facebook 获得的响应,这应该可以帮助您调试实际问题是什么,要查找的日志行在您提供的 sn-p 中:
logger.debug("[Silhouette][%s] Access token response:...
所以请检查您的日志,在那里您应该会看到来自 Facebook 的响应,其中可能会显示一个错误,说明他们为什么不能给您access_token
。
【讨论】:
以上是关于剪影和移动应用程序的主要内容,如果未能解决你的问题,请参考以下文章