This library is no longer maintained and repository is archived.
Simple reactive extension, that adds support to Retrofit2 based projects which uses OAuth2 authentication.
This library is based on RxJava2.
RxOAuthManager
provides wrapping for RxJava2 streams, which automatically handles access token expiration and performs token refresh. In case of success, new credentials are stored inSharedPreferences
. When refresh token is invalid, the optional logic provided inonRefreshTokenFailed
is performed. With customErrorChecker
, the user may customize access and refresh tokens errors validationOAuthInterceptor
, which is provided byRxOAuthManager
addsAuthorization
header with access token to OkHttp requestsDefaultOAuthCredentials
is the default implementation ofOAuthCredentials
compile 'cz.ackee.rxoauth2:core:x.x.x'
Working sample is provided in app
module.
Create RxOAuthManager
typically in API access layer (in our case, ApiInteractorImpl):
class ApiInteractorImpl @Inject constructor(private val apiDescription: ApiDescription,
context: Context) : ApiInteractor {
private val rxOAuthManager: RxOAuthManager = RxOAuthManager(
context = context,
refreshTokenAction = { refreshToken ->
apiDescription.refreshToken(refreshToken) // API call for token refresh
},
onRefreshTokenFailed = { err ->
// Fallback, e.g. log out
})
}
You can save OAuth credentials with saveCredentials(credentials: OAuthCredentials)
method. You may want to do this after receiving credentials from server, e.g. after login or sign in.
apiDescription.login(name, password)
.doOnNext { credentials -> rxOAuthManager.saveCredentials(credentials) }
After logging out, you may want to remove credentials from the store.
apiDescription.logout()
.doOnNext { response -> rxOAuthManager.clearCredentials() }
To wrap your requests with OAuth handling, just call wrapWithOAuthHandlingObservable()
, wrapWithOAuthHandlingSingle()
or wrapWithOAuthHandlingCompletable()
on the stream you want. RxOAuthManager
supports Observable
, Single
and Completable
.
apiDescription.getData().wrapWithOAuthHandlingSingle(rxOAuthManager)
To avoid boilerplate for each request, you may use another library we developed - RxWrapper, which wraps the whole interface functions that use RxJava2 with custom Transformer
s using compose
operator. Now you need to apply wrapWithOAuthHandling...()
only once and work with generated wrapper insteado of original apiDescription
. If you want to exclude some function from wrapping, just mark it with @NoCompose
annotation.
Initialization in constructor of Api Interactor:
private var apiWrapper = ApiDescriptionWrapped(apiDescription, object : IComposeWrapper {
override fun <T : Any?> wrapSingle(): SingleTransformer<T, T> {
return rxOAuthManager.transformSingle()
}
override fun wrapCompletable(): CompletableTransformer {
return rxOAuthManager.transformCompletable()
}
override fun <T : Any?> wrapObservable(): ObservableTransformer<T, T> {
return rxOAuthManager.transformObservable()
}
})
From version 2.0.0, new module is available. Now RxOAuth2 wrapping may be provided as Retrofit2 CallAdapter
.
compile 'cz.ackee.rxoauth2:retrofit-adapter:x.x.x'
When creating your API service, just provide RxOAuthCallAdapterFactory
to Retrofit builder. If you want to exclude some function from wrapping, just mark it with @IgnoreAuth
annotation.
val apiDescription: ApiDescription = retrofitBuilder
.client(OkHttpClient.Builder()
.addNetworkInterceptor(rxOAuthManager.provideAuthInterceptor())
.build())
.addCallAdapterFactory(RxOAuthCallAdapterFactory(rxOAuthManager))
.build()
.create(ApiDescription::class.java)
- Release of lib with RxJava2 support
- Abstract checker for errors to give user ability to change behavior when to refresh token
- Artifact naming change:
cz.ackee.rxoauth2:rxOAuth
->cz.ackee.rxoauth2:core
- New module
Retrofit adapter
is created with artifactcz.ackee.rxoauth2:retrofit-adapter
, more on this in section Retrofit2 adapter RxOAuthManager
now acceptsContext
or customSharedPreferences
in the constructor instead ofOAuthStore
RxOAuthManager
now uses lambda actionrefreshTokenAction: (String) -> Single<OAuthCredentials>
instead ofRefreshTokenService
classRxOAuthManager
now uses lambda actiononRefreshTokenFailed: (Throwable) -> Unit
instead ofRefreshTokenFailedListener
class.- New property
expiresIn
is added toOAuthCredentials
. NowOAuthStore
stores token expiration time andRxOAuthManager
controls it locally before each request to avoid redundant API calls if access token is expired OAuthStore
is now an internal class. The only way to store credentials issaveCredentials(credentials: OAuthCredentials)
onRxOAuthManager
. The same is withclearCredentials()
AuthInterceptor
is renamed toOAuthInterceptor
an has now only internal constructor. The only way to get an instance isprovideAuthInterceptor()
function onRxOAuthManager
DefaultOAuthCredentials
class is added as default implementation ofOAuthCredentials
DefaultErrorChecker
functions were renamed
- Rename
wrapWithOAuthHandlingObservable()
,wrapWithOAuthHandlingSingle()
andwrapWithOAuthHandlingCompletable()
functions, returning transformers totransformObservable()
,transformSingle()
andtransformCompletable()
respectively - Add Kotlin extensions for RxJava entities:
wrapWithOAuthHandlingObservable()
,wrapWithOAuthHandlingSingle()
andwrapWithOAuthHandlingCompletable()
- Fix
NullPointerException
onCompletable
handling due to null body