如何使用 GET 请求 API 在 Kotlin 中进行基本身份验证登录?

Joã*_*ins 3 authentication android kotlin okhttp retrofit2

我正在尝试制作一个在 Android Studio 中制作的登录屏幕来与 Kotlin 配合使用,但我在制作一个将基本身份验证“附加”到所有请求的类时遇到了麻烦。为此,我使用 Retrofit2 和 OkHttp3。

这些是我的代码中的相关类:

GET_LOGIN.kt

package com.joaomartins.srodkitrwale

import okhttp3.OkHttpClient
import retrofit2.Call
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.Headers

interface GET_LOGIN {
    @GET("login")
    fun getAccessToken() : Call<String>
}
Run Code Online (Sandbox Code Playgroud)

改造客户端.kt

package com.joaomartins.srodkitrwale

import android.app.Application
import android.util.Base64
import kotlinx.android.synthetic.main.activity_login.*
import okhttp3.Interceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import okhttp3.logging.HttpLoggingInterceptor

    val username = Login().userTxt.text
    val password = Login().passTxt.text
    val credentials = username + ":" + password
    val AUTH = "Basic " + Base64.encodeToString(credentials.toByteArray(Charsets.UTF_8), Base64.DEFAULT).replace("\n", "")

    val retrofit = RetrofitClient().init()
            //.getBytes(), Base64.DEFAULT).replace("\n", "")
//val AUTH2 = java.util.Base64.getEncoder().encode((username + ":" + password).toByteArray()).toString(Charsets.UTF_8)

class RetrofitClient {
    // Initializing Retrofit
    fun init() : Retrofit{

        // Creating the instance of an Interceptor
        val logging = HttpLoggingInterceptor()
        logging.level = HttpLoggingInterceptor.Level.BODY


        // Creating the OkHttp Builder
        val client = OkHttpClient().newBuilder()


        // Creating the custom Interceptor with Headers
        val interceptor = Interceptor { chain ->
            val request = chain?.request()?.newBuilder()?.addHeader("Authorization", AUTH)?.build()
            chain?.proceed(request)
        }
        client.addInterceptor(interceptor) // Attaching the Interceptor

        // Creating the instance of a Builder
        return Retrofit.Builder()
                .baseUrl("https://srodki.herokuapp.com/")   // The API server
                .client(client.build())                                     // Adding Http Client
                .addConverterFactory(GsonConverterFactory.create()) // Object Converter
                .build()
    }

    fun providesGetLogin(): GET_LOGIN = retrofit.create(GET_LOGIN::class.java)
}
Run Code Online (Sandbox Code Playgroud)

登录.kt

package com.joaomartins.srodkitrwale

import android.content.Intent
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.text.Editable
import android.util.Base64
import android.util.Log
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_login.*
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit

class Login : AppCompatActivity() {

    val apiLogin = RetrofitClient().providesGetLogin().getAccessToken()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_login)

        loginBtn.setOnClickListener {
            val user = userTxt.text
            val pass = passTxt.text

            if (validateLogin(user, pass)){
                login(user, pass)
            }
        }
    }

    fun validateLogin(user: Editable, pass: Editable): Boolean {
        if (user == null || user.trim().isEmpty()){
            Toast.makeText(this, "Missing Username or Password", Toast.LENGTH_SHORT).show()
            return false
        }
        if (pass == null || pass.trim().isEmpty()){
            Toast.makeText(this, "Missing Username or Password", Toast.LENGTH_SHORT).show()
            return false
        }
        return true
    }

    fun login(user: Editable, pass: Editable) {
        /*val intent = Intent(this, List_users::class.java)
        startActivity(intent)*/
        apiLogin.enqueue(object : Callback<String> {
            override fun onResponse(call: Call<String>, response: Response<String>) {
                Log.d("check", "Reached this place")
                if(!response.isSuccessful)
                    Log.d("failed", "No Success")
                Toast.makeText(this@Login, "Login Successful!", Toast.LENGTH_SHORT).show()
                val intent = Intent(this@Login, List_users::class.java)
                startActivity(intent)
            }

            override fun onFailure(call: Call<String>, t: Throwable) {
                Toast.makeText(this@Login, "Login Failed.", Toast.LENGTH_SHORT).show()
            }
        })

    }

}
Run Code Online (Sandbox Code Playgroud)

负责创建具有加密身份验证的请求的类是RetrofitClient类。

我相信错误存在于以下代码行中:

val username = Login().userTxt.text
val password = Login().passTxt.text
val credentials = username + ":" + password
val AUTH = "Basic " + Base64.encodeToString(credentials.toByteArray(Charsets.UTF_8), Base64.DEFAULT).replace("\n", "")
Run Code Online (Sandbox Code Playgroud)

应该有一种更简单的方法来做到这一点,但我仍在学习 Android 和 Kotlin。

小智 5

用这个:

val client = OkHttpClient()
val credential = Credentials.basic("username", "secret")
val request = Request.Builder()
        .url("https://yourserver.com/api")
        .addHeader("Authorization", credential)
        .build()

client.newCall(request).enqueue(object : Callback{
    override fun onFailure(call: Call, e: IOException) {
        TODO("Not yet implemented")
    }

    override fun onResponse(call: Call, response: Response) {
        println(response.body()?.string())
    }
})
Run Code Online (Sandbox Code Playgroud)