Расчет oauth_signature и oauth_nonce в Kotlin - PullRequest
0 голосов
/ 29 января 2020

Я занимаюсь разработкой приложения для Twitter android, в котором есть функция входа в систему с помощью Twitter. Вход работает отлично. Но моя проблема в том, что я хочу искать пользователей. Я погуглил это и нашел конечную точку.

https://api.twitter.com/1.1/users/search.json

Затем я создал модифицированную функцию для поиска пользователей:

@GET("users/search.json")
suspend fun searchUser(
    @Header("authorization") header: String,
    @Query("q") search: String
) : Response<List<InspectedUserPOJO>>

Затем вызвал ее из фрагмента следующим образом:

CoroutineScope(viewModelJob).launch {
            withContext(IO) {
                try {
                    val response = RetrofitInstance.retrofitInstance!!.searchUser(generateHeader(),"teyyihan")
                    if (response.isSuccessful) {
                        if (response.body() != null) {
                           // getting response
                        } else {
                        }
                    } else {} } catch (e: Exception) {}
            }

        }

Вот generateHeader ( ) функция:

fun generateHeader(): String{
    var header = "OAuth oauth_consumer_key=\""+/* my consumer key*/+"\",oauth_token=\""+CurrentUserInfo.authToken+"\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1580300189\",oauth_nonce=\"iBryT2SIbXa\",oauth_version=\"1.0\",oauth_signature=\"EvMhzhOKw%2BVhRKw5Iz%2F48VdWdlQ%3D\""
    return header
}

На самом деле этот заголовок от почтальона. Я проверил этот заголовок, и он работал отлично. Однако каждый раз, когда я отправлял запрос oauth_nonce и oauht_signature об изменениях. Я попытался изменить oauth_token с моим oauht_token, но он не работает. Так, как я могу вычислить oauth_nonce и oauth_signature?

Также я работал с java в течение 1 года, если вы знаете способ java, пожалуйста, ответьте мне.

Ответы [ 2 ]

0 голосов
/ 29 января 2020

Я нашел решение, оно использует модернизацию, и вам не нужно явно вычислять oauth_nonce или oauth_signature.

Сначала вам нужно реализовать эти библиотеки:

implementation 'se.akerfeldt:okhttp-signpost:1.1.0'
implementation 'com.squareup.okhttp3:okhttp:3.0.0-RC1'
implementation 'oauth.signpost:signpost-core:1.2.1.2'
implementation("com.squareup.okhttp3:logging-interceptor:4.3.1")

У нас будет класс с именем RetrofitClient:

class RetrofitClient {
companion object {
    private var retrofit: Retrofit? = null
    private val gSON = GsonBuilder()
        .setLenient()
        .create()

    fun getClient(baseUrl: String, consumer: OkHttpOAuthConsumer): Retrofit? {
        val logging = HttpLoggingInterceptor()
        if (BuildConfig.DEBUG) {
            logging.level = HttpLoggingInterceptor.Level.BODY
        } else {
            logging.level = HttpLoggingInterceptor.Level.NONE
        }

        val httpClient = OkHttpClient.Builder()
        httpClient.connectTimeout(60000, TimeUnit.SECONDS)
        httpClient.writeTimeout(120000, TimeUnit.SECONDS)
        httpClient.readTimeout(120000, TimeUnit.SECONDS)
        httpClient.retryOnConnectionFailure(true)
        httpClient.addInterceptor(SigningInterceptor(consumer))
        httpClient.addInterceptor { chain ->
            val request = chain.request()
            val requestBuilder = request.newBuilder()
            val modifiedRequest = requestBuilder.build()
            chain.proceed(modifiedRequest)
        }

        httpClient.addNetworkInterceptor(logging)

        if (retrofit == null) {
            retrofit = Retrofit.Builder()
                .baseUrl(baseUrl)
                .addConverterFactory(GsonConverterFactory.create(gSON))
                .client(httpClient.build())
                .build()
        }
        return retrofit
    }

}

}

И, наконец, в Ваш интерфейс Retrofit создает сопутствующий объект:

companion object {
    fun getOauthAPIService(): RetrofitTwitterAPI? {
        val consumer = OkHttpOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET)
        consumer.setTokenWithSecret(CurrentUserInfo.authToken, CurrentUserInfo.authTokenSecret)
        return RetrofitClient.getClient(BASE_URL, consumer)?.create(YOUR_RETROFIT_INTERFACE::class.java)
    }

}

Таким образом, вы можете звонить YOUR_RETROFIT_INTERFACE.getOauthAPIService() и совершать вызовы https. Дооснащение и все эти коды будут обрабатывать дополнительные заголовки, такие как oauht_nonce, oauth_signature et c.

0 голосов
/ 29 января 2020

Одним из возможных решений является добавление заголовка с использованием и перехватчика, а затем построение модифицированного объекта:

Interface YourService:{
//Your method 
@GET("users/search.json")
suspend fun searchUser(
    @Header("authorization") header: String,
    @Query("q") search: String
) : Response<List<InspectedUserPOJO>>

companion object:{
 fun createService(): YourService {



            val headerAuthorizationInterceptor = Interceptor { chain ->
                var request = chain.request()
                val headers = request.headers().newBuilder().add("OAuth oauth_consumer_key", /*consumer key*/)
                        .add("Second Header", Second key)
                        .add("Content-Type", "application/json").build() //I am guessing content type is application/json

                request = request.newBuilder().headers(headers).build()
                chain.proceed(request)
            }


            val okHttpClient = OkHttpClient.Builder()
                    .readTimeout(20, TimeUnit.SECONDS)
                    .connectTimeout(20, TimeUnit.SECONDS)
                    .addInterceptor(headerAuthorizationInterceptor)
                    .build()

            val retrofit = Retrofit.Builder()
                    .baseUrl(Your base url)
                    .client(okHttpClient)
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .addConverterFactory(ScalarsConverterFactory.create())
                    .addConverterFactory(GsonConverterFactory.create())
                    .build()
            return retrofit.create(YourService::class.java)
        }
    }
}

Когда вы завершаете sh реализацию этого, переменная headerAuthorizationInterceptor - это та, куда вы добавляете ваши заголовки. Надеюсь, это поможет

...