安卓|使用 retrofit2 和本地 API 的基本身份验证 [英] Android| Basic Auth using retrofit2 and local API

查看:50
本文介绍了安卓|使用 retrofit2 和本地 API 的基本身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始制作一个应用程序并首先将它连接到一个模拟 API.现在我想将它连接到在我的 PC 上运行的 API.

I started making an app and connected it to a mock API at first. Now I want to connect it an API that runs on my PC.

首先,我正在尝试实现登录访问.由于我的 API 的基本 URL 是

For starters, I'm trying to implement the login access. Since my API's base URL was http://localhost:5000/energy/api/ I changed it to http://<< MyIPAddress >>:5000/energy/api/ (don't know if this is right yet). I'm testing it on my actual phone. But with my code username and password are passed on as parameters, while I'd like to login with basic auth (this is how I do it in Postman). For example this is how I want the authentication to be done:

但是通过我的代码,我得到了这个:

这是我的请求管理器:

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)

我的 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 编辑和更正)

My API.kt code: (EDITED AND CORRECTED by user 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;
    }

}

有人可以帮助我进行基本身份验证吗?我的基本 URL 是否也有问题?(添加 IP 而不是本地主机).任何提示将不胜感激.

Could someone help me with Basic Auth? Is there also a problem with my base URL? (added IP instead of localhost). Any tips would be very appreciated.

附注.对于http安全问题,我已经添加了

PS. for the http security issue, I have already added

android:usesCleartextTraffic="true"

在我的AndroidManifest.xml

推荐答案

Basic Auth 需要以下格式的 Authorization 标头:"基本" + Base64.encode(<用户名>:<密码>)

Basic Auth requires an Authorization header in this format: "Basic " + Base64.encode(<username>:<password>)

你应该像这样改变你的 Api 接口

You should change your Api interface like this

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

现在您可以像这样向调用添加 Auth 标头:

Now you can add an Auth header to the call like so:

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

val call = RequestManager.service.login("Basic $base64".trim())

这篇关于安卓|使用 retrofit2 和本地 API 的基本身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆