I'm trying to make a Login screen I've made in Android Studio to work with Kotlin but I'm having troubles making a class that will "attach" the Basic Authentication to all the requests. To do this I am using Retrofit2 and OkHttp3.
These are the relevant classes in my code:
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>
}
RetrofitClient.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)
}
Login.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()
}
})
}
}
The class that would be responsible for the creation of the request with the encrypted authentication is the RetrofitClient class.
I believe the error lies within the following lines of code:
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", "")
There should be an easier way to do this but I am still learning Android and Kotlin.
Use this:
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())
}
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With