WebView, Cookies et Client HTTP
Bonjour,
Voici le contexte : Une application Android qui va accéder à des pages web dont certaines nécessitent une authentification.
L'application a le cycle suivant : SplashScreen (Activity) -> LogScreen (Activity) -> MainScreen (SherlockFragmentActivity) -> WebViewFragment (SherlockFragment). Elle utilise également une classe de configuration du client HTTP.
Au niveau du LogScreen l'application affiche un formulaire de login qui grâce au client HTTP envoi en POST les informations nécessaires et suivant la réponse de la page de traitement du formulaire, lance l'activité suivante ou redemande les identifiants.
Toujours au niveau du login je récupère les cookies (session + perso) et les stocke. J'ai testé leur présence : Tout est ok.
Le problème est le suivant une fois le fragment contenant la WebView instancié, je synchronise le CookieStore du client HTTP avec le CookieManager de la WebView. Mais les pages loadées depuis la WebView agissent comme si les cookies n’existaient pas.
Voici le code du LogScreen :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
| import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class XXX_LogScreen extends Activity implements OnClickListener{
public String sLogin = null;
public String sPassword = null;
private EditText login = null;
private EditText password = null;
private Button guest = null;
private Button submit = null;
static DefaultHttpClient httpClient = XXX_AppSettings.getClient();
public static Cookie cookie = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.log_screen);
login = (EditText) findViewById(R.id.login_etw);
password = (EditText) findViewById(R.id.password_etw);
guest = (Button) findViewById(R.id.guest_b);
submit = (Button) findViewById(R.id.submit_b);
guest.setOnClickListener(this);
submit.setOnClickListener(this);
}
public boolean isNetworkAvailable() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
return cm.getActiveNetworkInfo().isConnectedOrConnecting();
}
@Override
public void onClick(View v) {
if(v.getId() == R.id.guest_b){
sLogin = "guest";
sPassword = "pass_guest";
if (isNetworkAvailable()) {
sendPostRequest(sLogin, sPassword);
}
else {
Toast.makeText(XXX_LogScreen.this, "Vous n'êtes pas connecté à internet.", Toast.LENGTH_LONG).show();
}
}
else if(v.getId() == R.id.submit_b){
sLogin = login.getEditableText().toString();
sPassword = password.getEditableText().toString();
System.out.println("Given username :" + sLogin + " Given password :" + sPassword);
if (sLogin.length() == 0) {
Toast.makeText(XXX_LogScreen.this, "Veuillez saisir votre adresse email.", Toast.LENGTH_LONG).show();
}
else if (sPassword.length() == 0){
Toast.makeText(XXX_LogScreen.this, "Veuillez saisir votre mot de passe.", Toast.LENGTH_LONG).show();
}
else {
if (isNetworkAvailable()) {
sendPostRequest(sLogin, sPassword);
}
else {
Toast.makeText(XXX_LogScreen.this, "Vous n'êtes pas connecté à internet.", Toast.LENGTH_LONG).show();
}
}
}
}
private void sendPostRequest(String givenUsername, String givenPassword) {
class SendPostReqAsyncTask extends AsyncTask<String, Void, String>{
@Override
protected String doInBackground(String... params) {
String paramUsername = params[0];
String paramPassword = params[1];
System.out.println("*** doInBackground ** paramUsername : " + paramUsername + " paramPassword : " + paramPassword);
HttpPost httpPost = new HttpPost("http://www.xxxxxxxx.xxx/xxxxxxx/app_connect.php");
BasicNameValuePair usernameBasicNameValuePair = new BasicNameValuePair("paramUsername", paramUsername);
BasicNameValuePair passwordBasicNameValuePAir = new BasicNameValuePair("paramPassword", paramPassword);
List<NameValuePair> nameValuePairList = new ArrayList<NameValuePair>();
nameValuePairList.add(usernameBasicNameValuePair);
nameValuePairList.add(passwordBasicNameValuePAir);
try {
UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(nameValuePairList);
httpPost.setEntity(urlEncodedFormEntity);
try {
HttpResponse httpResponse = httpClient.execute(httpPost);
System.out.println("Post logon cookies:");
List<Cookie> cookies = httpClient.getCookieStore().getCookies();
if (cookies.isEmpty()) {
System.out.println("None");
}
else {
for (int i = 0; i < cookies.size(); i++) {
cookie = cookies.get(i);
System.out.println("- " + cookies.get(i).toString());
}
}
InputStream inputStream = httpResponse.getEntity().getContent();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
StringBuilder stringBuilder = new StringBuilder();
String bufferedStrChunk = null;
while((bufferedStrChunk = bufferedReader.readLine()) != null){
stringBuilder.append(bufferedStrChunk);
}
return stringBuilder.toString();
} catch (ClientProtocolException cpe) {
System.out.println("First Exception caz of HttpResponese :" + cpe);
cpe.printStackTrace();
} catch (IOException ioe) {
System.out.println("Second Exception caz of HttpResponse :" + ioe);
ioe.printStackTrace();
}
} catch (UnsupportedEncodingException uee) {
System.out.println("An Exception given because of UrlEncodedFormEntity argument :" + uee);
uee.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(result.equals("working")){
Intent intent = new Intent(XXX_LogScreen.this, XXX_MainScreen.class);
startActivity(intent);
finish();
}
else{
Toast.makeText(getApplicationContext(), "Identification incorrecte !", Toast.LENGTH_LONG).show();
}
}
}
SendPostReqAsyncTask sendPostReqAsyncTask = new SendPostReqAsyncTask();
sendPostReqAsyncTask.execute(givenUsername, givenPassword);
}
} |
Le code du WebViewFragment :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
| import java.util.List;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;
import com.actionbarsherlock.app.SherlockFragment;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.ActionBar.Tab;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.view.MenuInflater;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.support.v4.app.FragmentTransaction;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.WebBackForwardList;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class XXX_WebViewFragment extends SherlockFragment implements ActionBar.TabListener {
private static final String STATE_SELECTED_NAVIGATION_ITEM = "selected_navigation_item";
private WebView webView = null;
private MenuItem loginItem = null;
private WebSettings webSettings = null;
private WebViewClient webViewClient = null;
private CookieManager cookieManager = null;
private com.actionbarsherlock.app.ActionBar actionBar = null;
private static DefaultHttpClient myHttpClient = XXX_AppSettings.getClient();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(STATE_SELECTED_NAVIGATION_ITEM, getSherlockActivity().getSupportActionBar().getSelectedNavigationIndex());
webView.saveState(outState);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
actionBar = getSherlockActivity().getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
inflater.inflate(R.menu.main_screen_menu, menu);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
@Override
@SuppressLint("SetJavaScriptEnabled")
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.webview_fragment, container, false);
webView = (WebView) view.findViewById(R.id.webView_wfs);
webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setGeolocationEnabled(true);
webSettings.setLoadWithOverviewMode(true);
webViewClient = new WebViewClient() {
public void onPageFinished(WebView view, String url) {
CookieSyncManager.getInstance().sync();
}
};
webView.setWebViewClient(webViewClient);
Cookie sessionInfo;
List<Cookie> cookies = myHttpClient.getCookieStore().getCookies();
if (! cookies.isEmpty()) {
CookieSyncManager.createInstance(webView.getContext());
cookieManager = CookieManager.getInstance();
for(Cookie cookie : cookies) {
sessionInfo = cookie;
String cookieString = sessionInfo.getName() + "=" + sessionInfo.getValue() + "; domain=" + sessionInfo.getDomain();
cookieManager.setCookie("xxxxx.xxx", cookieString);
CookieSyncManager.getInstance().sync();
}
}
setHasOptionsMenu(true);
return view;
}
[...]
} |
Et enfin le code du client http :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import android.app.Application;
public class XXX_AppSettings extends Application{
private static final DefaultHttpClient client = createClient();
@Override
public void onCreate(){
}
static DefaultHttpClient getClient(){
return client;
}
private static DefaultHttpClient createClient(){
final SSLSocketFactory sslSocketFactory = SSLSocketFactory.getSocketFactory();
BasicHttpParams params = new BasicHttpParams();
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schemeRegistry.register(new Scheme("https", sslSocketFactory, 443));
ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);
DefaultHttpClient httpclient = new DefaultHttpClient(cm, params);
httpclient.getCookieStore().getCookies();
return httpclient;
}
} |
Si quelqu'un a une idée, je suis preneur.
D'avance merci !