我使用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