play2.0实现新浪OAuth2.0
jopen
12年前
最近有个项目要使用微博联合登录,看了下java版的 sdk, 太麻烦了,本来就不太懂java, 人都凌乱了,oauth2授权流程不是很复杂,就自己写实现下吧,就当练手了。
库代码
package libs.oauth2 import play.api.libs.concurrent._ import play.api.libs.ws._ import play.core.parsers._ import play.api.libs.json._ case class OAuthKey(key:String, secret:String) case class AccessToken(token:String) case class AccessTokenError(error:String, errorCode:Int, request:String) case class OAuth2(authorizationUrl: String, accessToken: String, redirectUri: String, key:OAuthKey){ def authorization(responseType:String, params:Map[String, String]) = { val ism = if(authorizationUrl.indexOf("?") > 0) "&" else "?" authorizationUrl+ism+"client_id="+key.key+"&response_type="+responseType+"&redirect_uri="+java.net.URLEncoder.encode(redirectUri, "utf-8") } def getAccessToken(code:String):Either[AccessToken, AccessTokenError] = { val rs = WS.url(accessToken).withQueryString( ("client_id", key.key) ,("client_secret", key.secret) ,("grant_type", "authorization_code") ,("redirect_uri", redirectUri) ,("code", code)).post("content").value.get.body var jsonRs = Json.parse(rs) if(rs.indexOf("error") > 0){ Right(AccessTokenError((jsonRs \ "error").as[String],(jsonRs \ "error_code").as[Int], (jsonRs \ "request").as[String] )) }else{ Left(AccessToken((jsonRs \ "access_token").as[String])) } } }附上用例
object login extends Controller { val oauth2 = OAuth2( "https://api.weibo.com/oauth2/authorize", "https://api.weibo.com/oauth2/access_token", "http://xx.com/login/sinare", OAuthKey("key", "secret") ); def sina = Action{ Redirect(oauth2.authorization("code",Map())) } def sinare = Action{ implicit request => request.queryString.getOrElse("code", "".toSeq).mkString match { case code:String if !code.isEmpty => { oauth2.getAccessToken(code) match{ case Left(t) => { Ok("token:"+t.token) } case Right(error) => Ok("error"+error.error) } } case _ => Ok("error") } } }