zhyue 2016-01-27
OAuthLoginSolution(2)ScalaandCallbackURLs
OauthService.scalaCodestoGenerateAuthURL/FetchRefreshToken/FetchProfile
packageservices
importjava.util.Arrays;
importcom.google.api.client.googleapis.auth.oauth2.{GoogleTokenResponse,GoogleAuthorizationCodeRequestUrl}
importcom.jobs2careers.util.IncludeLogger
importmodels.{AccountProfileResponse}
importplay.api.libs.json.Json
importplay.api.libs.ws.{WSResponse,WS}
importutils.IncludeOauthConfig
importscala.concurrent.duration._
importscala.concurrent.Await
importscala.concurrent.Future
importplay.api.Play.current
importcom.google.api.client.auth.oauth2.Credential
importcom.google.api.client.auth.oauth2.TokenResponse
importcom.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow
importcom.google.api.client.http.GenericUrl
importcom.google.api.client.http.HttpRequest
importcom.google.api.client.http.HttpRequestFactory
importcom.google.api.client.http.HttpTransport
importcom.google.api.client.http.javanet.NetHttpTransport
importcom.google.api.client.json.JsonFactory
importcom.google.api.client.json.jackson2.JacksonFactory
importcom.google.api.services.gmail.GmailScopes
objectOauthServiceextendsIncludeOauthConfigwithIncludeLogger{
implicitvalaccountProfileResponseWrites=Json.writes[AccountProfileResponse]
implicitvalaccountProfileResponseReads=Json.reads[AccountProfileResponse]
valcallbackURL=OAUTH_CALLBACK_URI
valUSER_INFO_URL="https://www.googleapis.com/auth/userinfo.profile"
valEMAIL_INFO_URL="https://www.googleapis.com/auth/userinfo.email"
valUSER_PROFILE_URL="https://www.googleapis.com/oauth2/v1/userinfo"
valJSON_FACTORY:JsonFactory=newJacksonFactory()
valHTTP_TRANSPORT:HttpTransport=newNetHttpTransport()
defgenerateAuthURL(accountCode:String):String={
valflow:GoogleAuthorizationCodeFlow=newGoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT,JSON_FACTORY,OAUTH_CLIENT_ID,OAUTH_CLIENT_SECRET,
Arrays.asList(GmailScopes.MAIL_GOOGLE_COM,GmailScopes.GMAIL_READONLY,USER_INFO_URL,EMAIL_INFO_URL))
.setAccessType("offline")
.setApprovalPrompt("force")
.build()
valurl:GoogleAuthorizationCodeRequestUrl=flow.newAuthorizationUrl()
valurl_str=url.setRedirectUri(callbackURL).setState(accountCode).build()
//url_str=url_str+"&[email protected]";
returnurl_str
}
deffetchRefreshToken(accessToken:String):String={
valflow:GoogleAuthorizationCodeFlow=newGoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT,JSON_FACTORY,OAUTH_CLIENT_ID,OAUTH_CLIENT_SECRET,
Arrays.asList(GmailScopes.MAIL_GOOGLE_COM,GmailScopes.GMAIL_READONLY,USER_INFO_URL,EMAIL_INFO_URL))
.setAccessType("offline")
.setApprovalPrompt("force")
.build()
valresponse:GoogleTokenResponse=flow.newTokenRequest(accessToken)
.setRedirectUri(callbackURL).execute()
valrefreshToken=response.getRefreshToken()
logger.debug("Refreshtokensystemget="+refreshToken)
returnrefreshToken
}
deffetchEmail(refreshToken:String):Option[String]={
valflow:GoogleAuthorizationCodeFlow=newGoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT,JSON_FACTORY,OAUTH_CLIENT_ID,OAUTH_CLIENT_SECRET,
Arrays.asList(GmailScopes.MAIL_GOOGLE_COM,GmailScopes.GMAIL_READONLY,USER_INFO_URL,EMAIL_INFO_URL))
.setAccessType("offline")
.setApprovalPrompt("force")
.build()
logger.debug("RefreshToken="+refreshToken)
valtokenResponse:TokenResponse=newTokenResponse()
tokenResponse.setRefreshToken(refreshToken)
valcredential:Credential=flow.createAndStoreCredential(tokenResponse,null)
valrequestFactory:HttpRequestFactory=HTTP_TRANSPORT.createRequestFactory(credential)
//Makeanauthenticatedrequest
valgenericUrl:GenericUrl=newGenericUrl(USER_INFO_URL)
valrequest:HttpRequest=requestFactory.buildGetRequest(genericUrl)
request.getHeaders().setContentType("application/json")
request.execute()
valaccessToken=credential.getAccessToken()
logger.debug("SystemgetthenewAccessToken="+accessToken)
//{
//"id":"114122167329329897934",
//"email":“[email protected]",
//"verified_email":true,
//"name":“SillycatMobile",
//"given_name":“sillycat",
//"family_name":"Mobile",
//"picture":"https://lh3.googleusercontent.com/-XdUIqdMkCWA/AAAAAAAAAAI/AAAAAAAAAAA/4252rscbv5M/photo.jpg",
//"locale":"en",
//"hd":“gmail.com"
//}
valurl=USER_PROFILE_URL+"?alt=json&access_token="+accessToken
logger.debug("URL="+url)
valfuture:Future[WSResponse]=WS.url(url).get()
valresult=Await.result(future,20seconds)
logger.debug("Fetchingtheprofileresponse="+result.json+"accessToken="+accessToken)
valemail=result.json.asOpt[AccountProfileResponse].map{profile=>
logger.info("Fetchingtheprofileinformation="+profile)
profile.email
}
returnemail
}
}
TheCallbackURLwhohandletheCallback
defaddSource=Action{request=>
logger.debug("Therequestbody="+request.body)
valaccessToken=request.getQueryString("code").getOrElse("")
valaccountCode=request.getQueryString("state").getOrElse("")
logger.debug("Firstaccesstokensystemget="+accessToken)
if(accessToken.isEmpty||accountCode.isEmpty){
valwarn_msg="Callbackaddsourcefail,requestparamsaccountCode="+accountCode
logger.warn(warn_msg)
BadRequest(Json.obj("status"->"Fail","message"->warn_msg))
}else{
valrefreshToken=OauthService.fetchRefreshToken(accessToken)
valemail=OauthService.fetchEmail(refreshToken).getOrElse("")
if(email.isEmpty){
valwarn_msg="Callbackaddsourcefail,failtofetchemailwithrefreshToken."
logger.warn(warn_msg)
BadRequest(Json.obj("status"->"Fail","message"->warn_msg))
}else{
//callactortoContextIOtoaddsource
sillycatIOthrottler!AccountSourceMessage(
accountCode,//accountCode
email,//emailsystemfetchfromprofile
email,//username,sameasemailforgoogle
refreshToken//refreshToken
)
Ok(Json.obj("status"->"OK"))
}
}
}
Thedependenciesinbuild.sbt
"com.google.api-client"%"google-api-client"%"1.20.0",
"com.google.oauth-client"%"google-oauth-client"%"1.20.0",
"com.google.apis"%"google-api-services-gmail"%"v1-rev36-1.20.0",
References: