安卓|使用 retrofit2 和本地 API 的基本身份验证 [英] Android| Basic Auth using retrofit2 and local 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屋!