TokenAuthenticator
@ থেবাং উত্তর মত ব্যবহার হ্যান্ডেল করার সঠিক উপায় refresh_token
।
এখানে আমার বাস্তবায়ন হয়েছে (আমি কোটলিন, ড্যাজার, আরএক্স ব্যবহার করছি তবে আপনি আপনার ক্ষেত্রে এটি প্রয়োগ করার জন্য এই ধারণাটি ব্যবহার করতে পারেন)
TokenAuthenticator
class TokenAuthenticator @Inject constructor(private val noneAuthAPI: PotoNoneAuthApi, private val accessTokenWrapper: AccessTokenWrapper) : Authenticator {
override fun authenticate(route: Route, response: Response): Request? {
val newAccessToken = noneAuthAPI.refreshToken(accessTokenWrapper.getAccessToken()!!.refreshToken).blockingGet()
accessTokenWrapper.saveAccessToken(newAccessToken) // save new access_token for next called
return response.request().newBuilder()
.header("Authorization", newAccessToken.token) // just only need to override "Authorization" header, don't need to override all header since this new request is create base on old request
.build()
}
}
@ ব্রাইস গ্যাবিন মন্তব্যের মতো নির্ভরতা চক্র প্রতিরোধের জন্য , আমি 2 ইন্টারফেসের মতো তৈরি করি
interface PotoNoneAuthApi { // NONE authentication API
@POST("/login")
fun login(@Body request: LoginRequest): Single<AccessToken>
@POST("refresh_token")
@FormUrlEncoded
fun refreshToken(@Field("refresh_token") refreshToken: String): Single<AccessToken>
}
এবং
interface PotoAuthApi { // Authentication API
@GET("api/images")
fun getImage(): Single<GetImageResponse>
}
AccessTokenWrapper
শ্রেণী
class AccessTokenWrapper constructor(private val sharedPrefApi: SharedPrefApi) {
private var accessToken: AccessToken? = null
// get accessToken from cache or from SharePreference
fun getAccessToken(): AccessToken? {
if (accessToken == null) {
accessToken = sharedPrefApi.getObject(SharedPrefApi.ACCESS_TOKEN, AccessToken::class.java)
}
return accessToken
}
// save accessToken to SharePreference
fun saveAccessToken(accessToken: AccessToken) {
this.accessToken = accessToken
sharedPrefApi.putObject(SharedPrefApi.ACCESS_TOKEN, accessToken)
}
}
AccessToken
শ্রেণী
data class AccessToken(
@Expose
var token: String,
@Expose
var refreshToken: String)
আমার ইন্টারসেপ্টর
class AuthInterceptor @Inject constructor(private val accessTokenWrapper: AccessTokenWrapper): Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val originalRequest = chain.request()
val authorisedRequestBuilder = originalRequest.newBuilder()
.addHeader("Authorization", accessTokenWrapper.getAccessToken()!!.token)
.header("Accept", "application/json")
return chain.proceed(authorisedRequestBuilder.build())
}
}
অবশেষে, যোগ Interceptor
এবং Authenticator
আপনার টু OKHttpClient
যখন তৈরি সেবা PotoAuthApi
ডেমো
https://github.com/PhanVanLinh/AndroidMVPKotlin
বিঃদ্রঃ
প্রমাণীকরণকারী প্রবাহ
- উদাহরণ এপিআই
getImage()
401 ত্রুটি কোড ফেরত দেয়
authenticate
ভিতরে ভিতরে পদ্ধতি বরখাস্ত করাTokenAuthenticator
হবে
- সিংক্রোনাইজ
noneAuthAPI.refreshToken(...)
বলা হয়
noneAuthAPI.refreshToken(...)
প্রতিক্রিয়া পরে -> নতুন টোকেন শিরোনামে যুক্ত হবে
getImage()
ইচ্ছা অটো নামক নতুন হেডার সঙ্গে ( HttpLogging
লগ ইন করতে হবে এই কলে) ( intercept
ভিতরে AuthInterceptor
উইল বলা হয় না )
getImage()
তবুও যদি ত্রুটি 401 এ ব্যর্থ হয় তবে authenticate
অভ্যন্তরীণ পদ্ধতিটি আবার এ্যাগেইন এবং অ্যাগেইইন বরখাস্তTokenAuthenticator
করবে তবে এটি কল পদ্ধতি সম্পর্কে অনেক সময় ত্রুটি ফেলবে ( )। আপনি গণনা প্রতিক্রিয়া দ্বারা এটি প্রতিরোধ করতে পারেন । উদাহরণস্বরূপ, আপনি যদি 3 বার পুনরায় চেষ্টা করার পরে থাকেন তবে শেষ হবে এবংjava.net.ProtocolException: Too many follow-up requests
return null
authenticate
getImage()
return response 401
যদি getImage()
প্রতিক্রিয়া সাফল্য => আমরা সাধারণত ফলাফলের হবে (যেমন আপনাকে কল getImage()
কোন ত্রুটি সহ)
আশা করি এটি সাহায্য করবে