我使用Silex在PHP中開發了一個API,我希望能夠從Android應用程序和網站訪問它。我已經開發了能夠完美訪問API的網站。從Android應用程序登錄到Silex REST API
我試圖對我的Android應用程序做同樣的事情,但它不工作。我遇到的問題是我真的不明白我如何以用戶身份登錄自己,使用我用於網站的相同方法。我使用Silex的SecurityServiceProvider來處理在我的網站上工作的登錄和令牌部分。
這裏是代碼:
SecurityServiceProvider在app.php:
<form class="form-horizontal" role="form" method="post" action="{{ path('login_check') }}">
<div class="form-group">
<label for="inputEmail1" class="col-lg-2 col-sm-2 control-label">Login</label>
<div class="col-lg-10">
<input type="text" class="form-control" id="login" name="_username" placeholder="Login">
</div>
</div>
<div class="form-group">
<label for="inputPassword1" class="col-lg-2 col-sm-2 control-label">Mot de Passe</label>
<div class="col-lg-10">
<input type="password" class="form-control" id="mdp" name="_password" placeholder="Mot de Passe">
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-2 col-lg-10">
<div class="checkbox">
<label>
<input type="checkbox"> Se Souvenir de Moi
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-2 col-lg-10">
<button type="submit" class="btn btn-danger">Connexion</button>
</div>
</div>
</form>
LoginActivity在Android的:在/登錄login.html.twig呼叫
$app->register(new Silex\Provider\SecurityServiceProvider(), array(
'security.firewalls' => array(
'login' => array(
'pattern' => '^/login$',
),
'secured' => array(
'pattern' => '^/',
'form' => array('login_path' => '/login', 'check_path' => '/login_check'),
'logout' => array('logout_path' => '/logout'),
'users' => function($app) {
return new App\User\Provider\UserProvider($app['db']);
}),
),
'security.role_hierarchy' => array(
'ROLE_USER' => array(),
'ROLE_ADMIN' => array('ROLE_USER'),
),
'security.access_rules' => array(
array('^/user', 'ROLE_USER'),
array('^/admin', 'ROLE_ADMIN'),
)
));
登錄部分:
public class LoginActivity extends AppCompatActivity {
private static final String TAG = "LoginActivity";
private static final int REQUEST_SIGNUP = 0;
@Bind(R.id._username) EditText username;
@Bind(R.id._password) EditText password;
@Bind(R.id.btn_login) Button _loginButton;
@Bind(R.id.link_signup) TextView _signupLink;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
ButterKnife.bind(this);
_loginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
login();
}
});
_signupLink.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Start the Signup activity
Intent intent = new Intent(getApplicationContext(), SignupActivity.class);
startActivityForResult(intent, REQUEST_SIGNUP);
finish();
overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
}
});
}
public void login() {
if (!validate()) {
onLoginFailed();
return;
}
_loginButton.setEnabled(false);
final ProgressDialog progressDialog = new ProgressDialog(LoginActivity.this,
R.style.AppTheme_Dark_Dialog);
progressDialog.setIndeterminate(true);
progressDialog.setMessage("Authenticating...");
progressDialog.show();
String _username = username.getText().toString();
String _password = password.getText().toString();
Call<User> userCall = APIClient.getApiInterface().getUser(_username, _password);
userCall.enqueue(new Callback<User>() {
@Override
public void onResponse(Call<User> call, Response<User> response) {
if (response.body() == null) {
// Toast
} else
{
}
}
@Override
public void onFailure(Call<User> call, Throwable t) {
Log.d("Going here", "Don't know why");
}
});
// TODO: Implement your own authentication logic here.
new android.os.Handler().postDelayed(
new Runnable() {
public void run() {
// On complete call either onLoginSuccess or onLoginFailed
onLoginSuccess();
// onLoginFailed();
progressDialog.dismiss();
}
}, 3000);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_SIGNUP) {
if (resultCode == RESULT_OK) {
// TODO: Implement successful signup logic here
// By default we just finish the Activity and log them in automatically
this.finish();
}
}
}
@Override
public void onBackPressed() {
// Disable going back to the MainActivity
moveTaskToBack(true);
}
public void onLoginSuccess() {
_loginButton.setEnabled(true);
finish();
}
public void onLoginFailed() {
Toast.makeText(getBaseContext(), "Login failed", Toast.LENGTH_LONG).show();
_loginButton.setEnabled(true);
}
public boolean validate() {
boolean valid = true;
String _username = username.getText().toString();
String _password = password.getText().toString();
if (_username.isEmpty()) {
username.setError("enter a valid email address");
Log.d(TAG, "Login");
valid = false;
} else {
username.setError(null);
}
if (_password.isEmpty() || _password.length() < 4) {
password.setError("between 4 and 10 alphanumeric characters");
valid = false;
} else {
password.setError(null);
}
return valid;
}
}
APIClient在安卓
public class APIClient {
public static final String BASE_URL = "http://localhost:8080/";
private static Retrofit retrofit = null;
public static Retrofit getClient() {
if (retrofit == null) {
retrofit = new Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create()).build();
}
return retrofit;
}
public static APIInterface getApiInterface() {
APIInterface apiService = APIClient.getClient().create(APIInterface.class);
return apiService;
}
}
APIInterface在安卓
public interface APIInterface {
@FormUrlEncoded
@POST("login")
Call<User> getUser(@Field("_username") String _username, @Field("_password") String _password);
}
因此從技術上講我想發送帶有域「_username」和「_password」會做一個形式,但顯然它不。
自從我開始在所有移動/網絡服務/網絡環境中學習和工作後的幾個月,我對所有事情都不是很熟悉。如果您需要更多關於代碼的信息,或者是否有更好的方法來完成,請告訴我。
將是很好的,如果你解釋爲什麼向下票:) – Slico
我居然沒有downvote,我不知道誰做的:/我會檢查你發給我的東西,謝謝你的回答! –
不要擔心倒票,我很好奇爲什麼倒票,因爲也許我不正確。提供的信息有用嗎? – Slico