Android 使用改进的令牌身份验证
场景是,我有一个登录活动,它将用户名和密码发送到php rest api,如果响应正常,它将显示一个新活动(这里是一个测试活动) 然后,在新的活动中,使用从登录过程中获得的令牌,我可以通过改装来查询数据库 问题是我需要保存登录尝试中的cookies,以便在下一个请求中使用它。Android 使用改进的令牌身份验证,android,retrofit2,Android,Retrofit2,场景是,我有一个登录活动,它将用户名和密码发送到php rest api,如果响应正常,它将显示一个新活动(这里是一个测试活动) 然后,在新的活动中,使用从登录过程中获得的令牌,我可以通过改装来查询数据库 问题是我需要保存登录尝试中的cookies,以便在下一个请求中使用它。 我正在使用改装:2.2.0和 我读 及 我检查了所有可能的解决方案 我的应用程序正常工作,没有发生错误,但我的第一个和第二个活动中的标题字段值不同 这是我的改装客户端: public class RetrofitClien
我正在使用改装:2.2.0和 我读 及 我检查了所有可能的解决方案 我的应用程序正常工作,没有发生错误,但我的第一个和第二个活动中的标题字段值不同 这是我的改装客户端:
public class RetrofitClient {
private static String BASE_URL = "http://192.168.0.100/rest/main.php/";
private static Retrofit retrofit = null;
public static Retrofit getRetroftInstance() {
if (retrofit == null) {
OkHttpClient cl = new OkHttpClient().newBuilder().addInterceptor(new AuthInterceptor()).build();
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
// .client(client)
.build();
}
return retrofit;
}}
这是身份验证接收器:公共类AuthInterceptor
实现拦截器{
@凌驾
公共响应拦截(链)
抛出IOException{
Request=chain.Request();
request=request.newBuilder()
.addHeader(“X-XSRF-TOKEN”,ServiceSharedPrefs.getInstance().getToken())
.build();
响应=链。继续(请求);
返回响应;
}
}
这是我的登录过程:
private void loginProcedure(final String username, final String password) {
//Creat a user base on the user input
UserDB user = new UserDB(username, password);
//send data to the api and get response
Call<ApiDB> call = retrofitInterfaceObject.checkCredentials(user);
call.enqueue(new Callback<ApiDB>() {
@Override
public void onResponse(Call<ApiDB> call, Response<ApiDB> response) {
//Unauthorized handling
if (response.code() == 401) {
Toast.makeText(LoginActivity.this, "in 401", Toast.LENGTH_SHORT).show();
ServiceDialog
.getInstance()
.CreateDialog(LoginActivity.this,
String.valueOf(response.code())
+ LoginActivity.this.getString(R.string.login_unauthorized_error_title)
, LoginActivity.this.getString(R.string.login_unauthorized_error_message)
, LoginActivity.this.getString(R.string.Generall_Ok_Text), null, null, null, false, false);
}
//Handling the 200 response : 2 possibility
else if (response.code() == 200) {
//if login ok
if (response.body().getLogin() != null) {
if (response.body().getLogin().contains("yes")) {
for(int i =0 ;i < response.headers().size();i++){
Log.v("mmmm login header:"+i,response.headers().name(i));
}
sharedPrefs.setToken(response.headers().get("X-XSRF-TOKEN"));
sharedPrefs.saveData(username, password);
LoginActivity.this.startActivity(new Intent(LoginActivity.this, test_check.class));
}
}
//if login not ok
else if (response.body().getError().contains("Error in authentication!")) {
ServiceDialog
.getInstance()
.CreateDialog(LoginActivity.this, LoginActivity.this.getString(R.string.login_credentials_error_title)
, LoginActivity.this.getString(R.string.login_credentials_error_message)
, LoginActivity.this.getString(R.string.Generall_Ok_Text), null, null, null, false, false);
}
}
//Handle other situations
else {
ServiceDialog
.getInstance()
.CreateDialog(LoginActivity.this, response.code() + " : " + LoginActivity.this.getString(R.string.login_null_error_title)
, LoginActivity.this.getString(R.string.login_null_error_message)
, LoginActivity.this.getString(R.string.Generall_Ok_Text), null, null, null, false, false);
}
}
@Override
public void onFailure(Call<ApiDB> call, Throwable t) {
ServiceDialog.getInstance().CreateDialog(LoginActivity.this, LoginActivity.this.getString(R.string.login_null_error_title)
, t.getMessage() + "\n" + t.getLocalizedMessage(), LoginActivity.this.getString(R.string.Generall_Ok_Text),
null, null, null, true, true);
}
});
private void登录过程(最终字符串用户名、最终字符串密码){
//根据用户输入创建用户
UserDB user=newuserdb(用户名、密码);
//将数据发送到api并获取响应
Call Call=interfaceobject.checkCredentials(用户);
call.enqueue(新回调(){
@凌驾
公共void onResponse(调用、响应){
//未经授权的处理
if(response.code()==401){
Toast.makeText(LoginActivity.this,“in 401”,Toast.LENGTH_SHORT.show();
服务对话框
.getInstance()
.CreateDialog(LoginActivity.this,
String.valueOf(response.code())
+LoginActivity.this.getString(R.string.login\u未经授权的\u错误\u标题)
,LoginActivity.this.getString(R.string.login\u未经授权的\u错误\u消息)
,LoginActivity.this.getString(R.string.Generall\u Ok\u Text),null,null,null,false,false;
}
//处理200响应:2种可能性
else if(response.code()==200){
//如果登录正常
if(response.body().getLogin()!=null){
if(response.body().getLogin()包含(“yes”)){
对于(int i=0;i
这是我的测试活动:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_check);
final TextView t = (TextView) findViewById(R.id.txviewtest);
//t.setText(ping("192.168.0.100"));
Call<UserDB> call = this.ret.get1(ServiceSharedPrefs.getInstance().getToken());
call.enqueue(new Callback<UserDB>() {
@Override
public void onResponse(Call<UserDB> call, Response<UserDB> response) {
for(int i =0 ;i < response.headers().size();i++){
Log.v("mmmm check header:"+i,response.headers().name(i));
}
t.append(ServiceSharedPrefs.getInstance().getToken());
t.append("\n");
t.append(String.valueOf(response.code()));
t.append("\n");
t.append(response.headers().toString());
t.append("\n");
t.append(response.body().toString());
}
@Override
public void onFailure(Call<UserDB> call, Throwable t) {
ServiceDialog.getInstance().CreateDialog(test_check.this, t.getMessage(),
null, getString(R.string.Generall_Ok_Text), null, null, null, true, true);
}
});
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity\u test\u check);
最终文本视图t=(文本视图)findViewById(R.id.txviewtest);
//t、 setText(ping(“192.168.0.100”));
Call Call=this.ret.get1(ServiceSharedPrefs.getInstance().getToken());
call.enqueue(新回调(){
@凌驾
公共void onResponse(调用、响应){
对于(int i=0;i
我的第一个标题:
登录标题:0:日期:2017年5月18日星期四08:10:50 GMT
登录头:1:Server:Apache/2.4.23(Win64)PHP/5.6.25
登录hea
***
public class AuthInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain)
throws IOException {
Request request = chain.request();
if(prefs!=null && prefs.hasToken()){//essentially checking if the prefs has a non null token
request = request.newBuilder()
.addHeader("Authenticator", prefs.getToken())
.build();
}
Response response = chain.proceed(request);
return response;
}
}
***
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
***
.addInterceptor(new AuthInterceptor())
//this is nota valid function.first we should ccreate a
//OkHttp client and add this intercept to it.
***
// .client(client)
.build();
public class RetrofitClient {
private static String BASE_URL = "http://192.168.0.100/rest/main.php/";
private static Retrofit retrofit = null;
public static Retrofit getRetroftInstance() {
if (retrofit == null) {
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addNetworkInterceptor(new SessionRequestInterceptor());
httpClient.addNetworkInterceptor(new ReceivedCookiesInterceptor());
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient.build())
.build();
}
return retrofit;
}}
public class ReceivedCookiesInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
if (!originalResponse.headers("Set-Cookie").isEmpty()) {
HashSet<String> cookies = new HashSet<>();
for (String header : originalResponse.headers("Set-Cookie")) {
cookies.add(header);
if(header.startsWith("XSRF-TOKEN")) {
String newCookie[]=header.split(";");
System.out.println("newCookie Length: "+newCookie.length);
for(String ss:newCookie) {
if(ss.startsWith("XSRF-TOKEN")) {
System.out.println("Cookies ss: " + ss);
sharedPrefs.setToken(ss);
}
}
}
}
}
return originalResponse;
}
}
public class SessionRequestInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
Request.Builder request = original.newBuilder();
request.header("Cookie",ServiceSharedPrefs.getInstance().getToken()));
request.method(original.method(), original.body());
return chain.proceed(request.build());
}
}