一些背景:
我在Android中有一个可以进行基本身份验证的项目。我在SLIM PHP框架中做了后端,并且可以正常工作。但是我想将Firebase集成到项目中,以便为用户存储一些图像以及基本的聊天功能。
因此,我使用mAuth.signInWithCustomToken()
据我了解,字符串令牌将在函数内部传递。
我将firebase/php-jwt
用于php部分,并在后端添加了几行。
我在projectname/public/index.php
上添加了以下功能:
function create_custom_token($uid) {
$service_account_email = "service account email here";
$private_key = "privatekey here";
$now_seconds = time();
$payload = array(
"iss" => $service_account_email,
"sub" => $service_account_email,
"aud" => "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
"iat" => $now_seconds,
"exp" => $now_seconds+(60*60), // Maximum expiration time is one hour
"uid" => $uid
);
return JWT::encode($payload, $private_key, "HS256");
}
要调用该函数,我将代码放在登录路由器下面:
if($result == USER_AUTHENTICATED){
$user = $db->getUserByUsername($username);
$response_data = array();
$response_data['error']=false;
$response_data['message'] = 'Login Successful';
$response_data['user']=$user;
$jwt = create_custom_token($username);
$response_data['token']=$jwt;
$response->write(json_encode($response_data));
return $response
->withHeader('Content-type', 'application/json')
->withStatus(200);
}
所以基本上,我将username
用作uid
,因为它是唯一的。
在Android上,在LoginActivity.java
@Override
public void onValidationSucceeded() {
String username = editTextUsername.getText().toString();
String password = editTextPassword.getText().toString();
ProgressDialog dialog = new ProgressDialog(this);
dialog.setMessage("Logging in...");
dialog.show();
dialog.setCancelable(false);
Call<LoginResponse> call = RetrofitClient
.getInstance().getApi().userLogin(username, password);
call.enqueue(new Callback<LoginResponse>() {
@Override
public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
LoginResponse loginResponse = response.body();
if (!loginResponse.isError()) {
mAuth.signInWithCustomToken(loginResponse.getToken())
.addOnCompleteListener(LoginActivity.this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
SharedPrefManager.getInstance(LoginActivity.this)
.saveUser(loginResponse.getUser());
dialog.dismiss();
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
finish();
} else {
// If sign in fails, display a message to the user.
dialog.dismiss();
Toast.makeText(LoginActivity.this, loginResponse.getToken(),
Toast.LENGTH_SHORT).show();
}
}
});
} else {
dialog.dismiss();
Toast.makeText(LoginActivity.this, response.body().getMessage(), Toast.LENGTH_LONG).show();
}
}
@Override
public void onFailure(Call<LoginResponse> call, Throwable t) {
Toast.makeText(LoginActivity.this, t.getMessage(), Toast.LENGTH_LONG).show();
dialog.dismiss();
}
});
}
这是LoginResponse
模型
public class LoginResponse {
private boolean error;
private String message;
private User user;
private String token;
public LoginResponse(boolean error, String message, User user, String token) {
this.error = error;
this.message = message;
this.user = user;
this.token = token;
}
public boolean isError() {
return error;
}
public String getMessage() {
return message;
}
public User getUser() {
return user;
}
public String getToken() {
return token;
}
}
使用邮递员测试API, This is the result from POSTMAN 因此,您可以说它运行良好。
但是在Android上,当我尝试登录时,通过提供相同的正确用户名和密码,会引发错误`
自定义令牌格式无效。请检查文档。 [SIGNATURE_INVALID]
以防万一,这是来自结果eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJmaXJlYmFzZS1hZG1pbnNkay1tY3l4MEBmbGl0dGVyLWMxNzU2LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic3ViIjoiZmlyZWJhc2UtYWRtaW5zZGstbWN5eDBAZmxpdHRlci1jMTc1Ni5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImF1ZCI6Imh0dHBzOlwvXC9pZGVudGl0eXRvb2xraXQuZ29vZ2xlYXBpcy5jb21cL2dvb2dsZS5pZGVudGl0eS5pZGVudGl0eXRvb2xraXQudjEuSWRlbnRpdHlUb29sa2l0IiwiaWF0IjoxNTM0MzQ4ODI5LCJleHAiOjE1MzQzNTI0MjksInVpZCI6Imp1c3Rpbi5sdWNhcyJ9.cQwNFWshi_0nMiZKpjXajJ4MnB9E7kGPlFB-kWZPmfo
有创意的人吗?也许我必须在客户端做些什么?
答案 0 :(得分:0)
对任何可能看到此内容的人。答案是:确保将PC /台式机/笔记本电脑设置为正确的时间/时区。发布问题后第二天得到答案。