当我们知道用户名/密码时,如何从Java/Scala进行OAuth认证



tl;dr -我想用我自己的用户名/密码从Java/Scala的桌面应用程序(不想打开浏览器)对OAuth 2.0 API进行身份验证。

为什么?我想用我自己的凭证从Java/Scala验证Pocket的v3 API,并获取我的未读项目。这是一个个人命令行工具,我不打算为一般用途发布。他们曾经有一个很好的基本验证API,但他们弃用了它,引入了OAuth 2.0,我不确定如何再做我想做的事情。

好的,所以事实证明这是可能的,前提是要先做好一些事情。你需要先用pocket注册一个应用程序,才能获得消费者密钥。你可以在这里设置:

http://getpocket.com/developer/apps/new

然后,手动执行下面链接的步骤2和3,以使您的新应用程序一次性通过您的口袋帐户。这是一个一次性的手动步骤,之后可以自动执行。第2步使用curl,第3步使用chrome浏览器

http://getpocket.com/developer/docs/authentication

然后,您需要找到您的口袋用户id值。对我来说,它是在一个cookie绑定到域名"getpocket.com",并有名称sess_user_id。有了消费者密钥和用户if,您就可以使用下面的代码来获得用于呼叫口袋的认证令牌。请注意,我使用的是dispatch 0.10.0和spray-json 1.2.3作为第三方库:

import dispatch._
import spray.json._
import scala.concurrent.ExecutionContext
import java.util.concurrent.Executors
import scala.concurrent.Await
import scala.concurrent.duration._
import com.ning.http.client.Cookie
case class CodeRequest(consumer_key:String, redirect_uri:String = "fake:uri")
object CodeRequest
case class CodeResponse(code:String)
object CodeResponse
case class AuthRequest(consumer_key:String, code:String)
object AuthRequest
case class AuthResponse(access_token:String, username:String)
object AuthResponse
object PocketJsonProtocol extends DefaultJsonProtocol {
  implicit val codeRequestFormat = jsonFormat2(CodeRequest.apply)
  implicit val codeResponseFormat = jsonFormat1(CodeResponse.apply)
  implicit val authRequestFormat = jsonFormat2(AuthRequest.apply)
  implicit val authResponseFormat = jsonFormat2(AuthResponse.apply)  
}
object PocketAuth {
  import PocketJsonProtocol._
  val JsonHeaders = Map("X-Accept" -> "application/json", "Content-Type" -> "application/json; charset=UTF-8")
  implicit val EC = ExecutionContext.fromExecutor(Executors.newCachedThreadPool())
  def authenticate(consumerKey:String, userId:String) = {
    val fut = for{
      codeResp <- requestCode(consumerKey)
      _ <- activateToken(codeResp, userId)
      authResp <- requestAuth(consumerKey, codeResp)
    } yield{
      JsonParser(authResp).convertTo[AuthResponse]
    }
    val auth = Await.result(fut, 5 seconds)
    auth.access_token
  }
  def requestCode(key:String) = {
    val req = url("https://getpocket.com/v3/oauth/request") <:< JsonHeaders << CodeRequest(key).toJson.toString
    Http(req.POST OK as.String).map(JsonParser(_).convertTo[CodeResponse])
  }
  def activateToken(codeResp:CodeResponse, userId:String) = {
    val req = (url("https://getpocket.com/auth/authorize") <<? Map("request_token" -> codeResp.code, "redirect_uri" -> "foo")).addCookie(
      new Cookie(".getpocket.com", "sess_user_id", userId, "/", 100, false))
    Http(req)
  }
  def requestAuth(key:String, codeResp:CodeResponse) = {
    val req = url("https://getpocket.com/v3/oauth/authorize") <:< JsonHeaders << AuthRequest(key, codeResp.code).toJson.toString
    Http(req.POST OK as.String)
  }
}

你所需要做的就是在PocketAuth对象上调用authenticate函数,它将返回String认证令牌。

是不是有点笨拙?是的,但那是因为他们真的不希望你自动化这个过程,但这是可能的,因为我让它重复工作。

上次我不得不这样做(Facebook登录),我使用分派并快速实现了OAuth 2.0所需的部分,多亏了分派,这相当容易和快速。

JSON解析现在集成在Scala标准库中,实现应该不会比在您提供的链接下编写的代码更复杂。

有一个叫做password的龙门类型,它必须被启用,然后你的令牌URL将像

/oauth/token?grant_type=password&username=&password=

和header包含client_id和secret作为基本身份验证查看此链接

相关内容

  • 没有找到相关文章

最新更新