取得授權碼後,我們就能準備取得我們的權杖了,我們需要再透過api 先取得短期權杖,再用短期權杖取得長期權杖,並儲存下來供使用者之後使用,讓我們照著官方的使用說明來實作吧
取得長期權杖,並儲存在本地端,以提供使用者之後能透過此權杖使用Instagram basic display 的api,Android 我們這邊透過MVVM 的架構,讓AccessTokenActivity
能夠取得長期權杖並儲存在本地端
API:
interface ApiInstagramService {
@FormUrlEncoded
@POST("oauth/access_token")
suspend fun getShortAccessTokenInfo(
@Field("client_id") clientId: String,
@Field("client_secret") clientSecret: String,
@Field("code") code: String,
@Field("grant_type") grantType: String,
@Field("redirect_uri") redirectUri: String
): ShortAccessTokenInfo
}
interface GraphInstagramService {
@GET("access_token")
suspend fun getLongAccessTokenInfo(
@Query("grant_type") grantType: String,
@Query("client_secret") clientSecret: String,
@Query("access_token") accessToken: String
): LongAccessTokenInfo
}
DataRepository
:
suspend fun getAccessToken(
clientId: String,
clientSecret: String,
code: String,
redirectUri: String
) {
withContext(Dispatchers.IO) {
getShortAccessToken(
clientId,
clientSecret,
code,
redirectUri
)
}
}
private suspend fun getShortAccessToken(
clientId: String,
clientSecret: String,
code: String,
redirectUri: String
) {
try {
val shortAccessTokenInfo = apiInstagramService.getShortAccessTokenInfo(
clientId = clientId,
clientSecret = clientSecret,
code = code,
grantType = "authorization_code",
redirectUri = redirectUri
)
Log.d(TAG, "shortAccessTokenInfo = $shortAccessTokenInfo")
preference.set(Constants.PREF_KEY_INSTAGRAM_USER_ID, shortAccessTokenInfo.userId)
val currentTimeMillis: Long = System.currentTimeMillis()
getLongAccessToken(shortAccessTokenInfo.accessToken, clientSecret, currentTimeMillis)
} catch (exception: UnknownHostException) { // Request Api when no internet
exception.printStackTrace()
Log.e(TAG, "shortAccessTokenInfo exception = $exception")
_accessTokenResult.postValue(false)
} catch (exception: Exception) {
exception.printStackTrace()
Log.e(TAG, "shortAccessTokenInfo exception = $exception")
_accessTokenResult.postValue(false)
}
}
private suspend fun getLongAccessToken(
shortAccessToken: String,
clientSecret: String,
currentTimeMillis: Long
) {
try {
val longAccessTokenInfo = graphInstagramService.getLongAccessTokenInfo(
grantType = "ig_exchange_token",
clientSecret = clientSecret,
accessToken = shortAccessToken
)
val expiredTimeMillis = currentTimeMillis + longAccessTokenInfo.expiresIn
preference.set(Constants.PREF_KEY_EXPIRED_MILLISECONDS, expiredTimeMillis)
preference.set(Constants.PREF_KEY_ACCESS_TOKEN, longAccessTokenInfo.accessToken)
_accessTokenResult.postValue(true)
} catch (exception: UnknownHostException) { // Request Api when no internet
exception.printStackTrace()
Log.e(TAG, "getLongAccessToken exception = $exception")
_accessTokenResult.postValue(false)
} catch (exception: Exception) {
exception.printStackTrace()
Log.e(TAG, "getLongAccessToken exception = $exception")
_accessTokenResult.postValue(false)
}
}
AccessTokenViewModel
:
fun getAssessToken(
clientId: String,
clientSecret: String,
code: String,
redirectUri: String
) {
viewModelScope.launch {
repository.getAccessToken(
clientId,
clientSecret,
code,
redirectUri
)
}
}