Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android |使用2和本地API的基本身份验证_Android_Api_Kotlin_Retrofit2_Basic Authentication - Fatal编程技术网

Android |使用2和本地API的基本身份验证

Android |使用2和本地API的基本身份验证,android,api,kotlin,retrofit2,basic-authentication,Android,Api,Kotlin,Retrofit2,Basic Authentication,我开始制作一个应用程序,并首先将其连接到一个模拟API。现在我想把它连接到一个在我的电脑上运行的API 首先,我尝试实现登录访问。由于我的API的基本URL是http://>:5000/energy/API/(不知道这是否正确)。我正在我的手机上测试。 但在我的代码中,用户名和密码作为参数传递,而我想使用基本身份验证登录(我在Postman中就是这样做的)。 例如,我希望通过以下方式进行身份验证: 但通过我的代码,我得到了以下信息: 这是我的请求管理器: object RequestMana

我开始制作一个应用程序,并首先将其连接到一个模拟API。现在我想把它连接到一个在我的电脑上运行的API

首先,我尝试实现登录访问。由于我的API的基本URL是http://>:5000/energy/API/(不知道这是否正确)。我正在我的手机上测试。 但在我的代码中,用户名和密码作为参数传递,而我想使用基本身份验证登录(我在Postman中就是这样做的)。 例如,我希望通过以下方式进行身份验证:

但通过我的代码,我得到了以下信息:

这是我的请求管理器:

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)
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()
    }
}
public class LoginResponse {

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

    public String getToken() {
        return token;
    }

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

}
有人能帮我做一下基本的授权吗? 我的基本URL也有问题吗?(添加了IP而不是本地主机)。 任何提示都将不胜感激

另外,关于http安全问题,我已经添加了

android:usesCleartextTraffic="true"
在myAndroidManifest.xml中

@Query
此批注用于“GET”方法

您需要在“POST”方法的函数名之前添加
@FormUrlEncoded
。对于“POST”方法,您还需要使用
@Field
而不是
@Query
。因此,API调用initerface的方法将变成这样

@POST("Login")
@FormUrlEncoded
fun login(@Field("username") username: String, @Field("password") password: String): Call<LoginResponse>
@POST(“登录”)
@FormUrlEncoded
有趣的登录(@Field(“用户名”)用户名:字符串,@Field(“密码”)密码:字符串):调用

基本身份验证需要以下格式的授权标头:
“Basic”+Base64.编码(:)

您应该像这样更改Api接口

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

做一个简单的测试来验证你的基本url,用你的设备尝试用browser@FranciscoBarrios例如,如果您想通过chrome导航到http://myIPaddress:5000/,我不能:/ok,我不确定这是否是问题所在,但您应该看到,您的pc可能有类似192.168.0.xxx的IP和您的手机(不是模拟器)应在同一段中,检查pc和手机的ip以确保;)@FranciscoBarrios我试着在android浏览器中运行基本url,但它说无法访问站点。您是否添加了基本的auth头来改进API类?您需要将授权头添加到请求中,并添加文本:
Basic Base64.encode(:)
例如
Authorization:Basic qwxhzgrpbjppcgvu2vzyw1l
这非常有用!我试过了,但仍然不起作用(因为它仍然存在身份验证问题),但我肯定修复了一个我甚至不知道存在的问题!谢谢我很愿意,但这并不能解决我的身份验证问题,这是这里的主要问题:/请尝试将您的IP更改为'10.0.2.2',我在我的实际手机上进行了测试,所以我认为这不起作用
interface Api {
    @POST("Login")
    fun login(@Header("Authorization") authorization: String): Call<LoginResponse>
}
val authPayload = "$userId:$password"
val data = authPayload.toByteArray()
val base64 = Base64.encodeToString(data, Base64.NO_WRAP)

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