使用Slim PHP和Android在Firebase中进行自定义令牌身份验证[错误无效令牌。请检查文档]

时间:2018-08-15 16:09:08

标签: php android firebase firebase-authentication slim

一些背景:

我在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

的令牌

有创意的人吗?也许我必须在客户端做些什么?

1 个答案:

答案 0 :(得分:0)

对任何可能看到此内容的人。答案是:确保将PC /台式机/笔记本电脑设置为正确的时间/时区。发布问题后第二天得到答案。