Android | Basi c Auth с использованием retrofit2 и локального API - PullRequest
2 голосов
/ 25 февраля 2020

Я начал создавать приложение и сначала подключил его к фиктивному API. Теперь я хочу подключить к нему API, который работает на моем P C.

. Для начала я пытаюсь реализовать вход в систему. Так как базовый URL моего API был http://localhost: 5000 / energy / api / , я изменил его на http: // << MyIPAddress >>: 5000 / energy / api / (не знаю, является ли это прямо пока). Я проверяю это на моем реальном телефоне. Но с моим кодом имя пользователя и пароль передаются в качестве параметров, в то время как я хотел бы войти с помощью basi c auth (именно так я делаю это в Postman). Например, вот как я хочу сделать аутентификацию: enter image description here

Но с моим кодом я получаю это: enter image description here

Это мой менеджер запросов:

object RequestManager {
    val interceptor = HttpLoggingInterceptor()
    val client = OkHttpClient.Builder().addInterceptor(interceptor).build()
    init {
        interceptor.level = HttpLoggingInterceptor.Level.BODY
    }

    val retrofit = Retrofit.Builder()
        .baseUrl("http://<<MYIP>>:5000/energy/api/")
        .addConverterFactory(GsonConverterFactory.create())
        .client(client)
        .build()

    val service = retrofit.create(Api::class.java)

My MainActivity.kt:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        login_button.setOnClickListener {
            buttonClicked()
        }

        if (getTokenFromPrefs()?.length!! > 0) {
            openSearchActivity()
        }
    }

    private fun buttonClicked() {
        val username = username_edittext.text.toString()
        val password = password_edittext.text.toString()
        Log.d("eeee","button clicked " + username_edittext.text.toString() + " password "+password_edittext.text.toString() )

        val call = RequestManager.service.login(username, password)
        call.enqueue(object : Callback<LoginResponse> {
            override fun onResponse(call: Call<LoginResponse>, response: Response<LoginResponse>) {
                if (response.isSuccessful ){
                        openSearchActivity()
                        saveTokenToPrefs(response.toString())
                    }else {

                }
            }

            override fun onFailure(call: Call<LoginResponse>, t: Throwable) {
            }
        })
    }

    val TOKENPREFSKEY = "tokenprefskey"
    private fun saveTokenToPrefs(token: String) {
        val pref = applicationContext.getSharedPreferences("CGEEnergy", 0)
        val editor = pref.edit()
        editor.putString(TOKENPREFSKEY, token)
        editor.commit()
    }

    private fun getTokenFromPrefs(): String? {
        val pref = applicationContext.getSharedPreferences("CGEEnergy", 0)
        return pref.getString(TOKENPREFSKEY, "")
    }

    private fun openSearchActivity() {
        val intent = Intent(this, SearchActivity::class.java)
        startActivity(intent)
        if (getTokenFromPrefs()?.length!! == 0) {
            openMainActivity()
        }
        finish()
    }
    private fun openMainActivity() {
        val intent = Intent(this, MainActivity::class.java)
        startActivity(intent)
        finish()
    }
}

Мой код API.kt: (ИЗМЕНЕНО И ИСПРАВЛЕНО пользователем Hello World )

interface Api {
    @POST("Login")
    @FormUrlEncoded
    fun login(@Field("username") username: String, @Field("password") password: String): Call<LoginResponse>
}

Мой LoginResponse. java Код:

public class LoginResponse {

    @SerializedName("token")
    @Expose
    private String token;

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }

}

Может ли кто-нибудь помочь мне с Basi c Аут? Есть ли проблема с моим базовым URL? (добавлен IP вместо localhost). Любые советы будут очень признательны.

PS. для проблемы безопасности http я уже добавил

android:usesCleartextTraffic="true"

в мой AndroidManifest. xml

Ответы [ 2 ]

1 голос
/ 25 февраля 2020

Basi c Для аутентификации требуется заголовок авторизации в этом формате: "Basic " + Base64.encode(<username>:<password>)

Вы должны изменить свой интерфейс Api следующим образом

interface Api {
    @POST("Login")
    fun login(@Header("Authorization") authorization: String): Call<LoginResponse>
}

Теперь вы можете добавить заголовок Auth к звонок как так:

val authPayload = "$userId:$password"
val data = authPayload.toByteArray()
val base64 = Base64.encodeToString(data, Base64.NO_WRAP)

val call = RequestManager.service.login("Basic $base64".trim())
1 голос
/ 25 февраля 2020
@Query

Эта аннотация используется для метода «GET».

Вам необходимо добавить @FormUrlEncoded перед именем функции для метода «POST». И вам также нужно использовать @Field вместо @Query для метода «POST». Таким образом, ваш метод для API Call initerface станет таким.

@POST("Login")
@FormUrlEncoded
fun login(@Field("username") username: String, @Field("password") password: String): Call<LoginResponse>
...