在原生android SDK中,我使用WebView展示网页
如果我在webview中直接load学校教务系统的登录页面,那么登录之后一切功能正常。
我想要实现免登陆,就是在android中储存账号和密码,在进去应用时便直接登录,我通过httpclient构造请求获取了sessionid,通过cookiemanager的setcookie方法携带sessionid请求个人信息主页,这次请求能显示正常的内容,代表此次登录成功了,但是,如果我reload或者访问教务系统中的功能时,会出现设备在其他地方登录的提示。经过分析之后,是因为我的sessionid在第一次登录之后被莫名改动了。
我的setcookie方法只在oncreate的时候调用,
比较玄学的是,在我的网络比较差的时候,功能正常运行的概率越大。我用浏览器对教务系统进行多次实验,发现当退出登录时教务系统会修改客户端的sessionid,sessionid过期时间为会话结束时。教务系统使用的是jsp
我不知道android webview什么时候算是会话结束,请问出现的问题是什么,如何解决
你遇到的问题可能与教务系统的安全性策略有关。当你尝试使用存储的Session ID 进行免登陆时,系统可能会检测到Session ID 发生了变化,这可能导致在后续操作中出现“设备在其他地方登录”的提示。
一些教务系统为了防止Session劫持等安全问题,会采取措施来确保每个会话都是唯一的,并在特定条件下自动终止会话。这也解释了你在网络较差时功能正常运行的概率较高,因为网络延迟可能导致服务器难以检测到会话的变化。
所以,你需要仔细观察一下这个token,cookie,以及会话session的组成成分,同时,要想完成抓包,可以试试fiddler,这个是比较专业的,你可以抓到登录的接口,自己去尝试写一个自动登录,同时注意一下,抓包需要再同一网络,还需要进行一系列配置,详情百度
你需要抓包去分析下他的登录接口
可以抓包看一下它的登录接口,然后f12看一下它是不是转头看那个直接把偷看改为有效期的头坑,然后你就不用登陆了,直接拿可以进入到系统。
【以下回答由 GPT 生成】
根据问题描述,主要问题是在使用WebView展示网页的过程中,需要实现免登录并保持会话稳定的功能。 具体问题包括: 1. 登录成功后,重新加载页面或访问教务系统功能时,会出现“设备在其他地方登录”的提示。 2. sessionid在第一次登录后被修改了,setcookie方法只在oncreate的时候调用,导致后续请求没有携带新的sessionid。 3. 在网络比较差的情况下,功能能够正常运行的概率更大。 4. Android WebView中何时算作会话结束。
这个问题可能是由于教务系统的会话管理机制导致的。在登录成功后,教务系统会生成新的sessionid,旧的sessionid失效。
解决方法: 1. 当在WebView中登录成功后,获取到新的sessionid。 2. 在WebView的WebViewClient中的onPageFinished()方法中,使用JavaScript的方式注入新的sessionid到WebView页面中,确保页面中的cookie与最新的sessionid一致: kotlin webView.loadUrl("javascript:document.cookie = 'sessionid=" + newSessionId + "';");
3. 这样,在WebView上后续发送的请求将携带新的sessionid,并不会出现设备在其他地方登录的提示。
解决方法: 1. 使用CookieManager的getCookie()方法获取到WebView的cookie字符串。 2. 在新的请求时,通过HttpURLConnection携带获取到的cookie,并发送请求获取最新的sessionid: kotlin val url = URL(requestUrl) val connection = url.openConnection() as HttpURLConnection connection.setRequestProperty("Cookie", cookie) connection.connect()
这样,在获取到新的sessionid后,再次使用setcookie方法更新WebView的cookie。
这可能是因为在网络比较差的情况下,请求的延迟导致了sessionid的更新。教务系统可能在较长时间内才对sessionid进行更新。
解决方法: 1. 可以尝试在登录成功后主动访问一些页面,以确保sessionid的及时更新。
在Android WebView中,会话的结束通常是由服务器端来决定的。常见的做法是在教务系统的后台设置session的过期时间,一般为30分钟或1小时。
解决方法: 1. 可以通过观察教务系统后台的session过期设置,了解会话的结束时间。 2. 在WebView中处理session过期的情况,比如通过WebView的WebViewClient的onReceivedError()方法来判断是否session过期,并重新登录。
以上是根据问题描述给出的解决方案和建议,希望对你有帮助。如果还有其他问题,请随时提问。
【相关推荐】
该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
问题出现的原因是Android WebView的Cookie处理机制。WebView在加载网页时,会将服务器返回的Cookie存储在本地,当再次访问该网站时,WebView会自动携带这些Cookie。但是,有些网站会在用户登录后修改或删除Cookie,导致WebView无法识别正确的Cookie,从而出现设备在其他地方登录的提示。
解决方法如下:
1、 使用HttpClient替换WebView直接加载登录页面。这样可以避免WebView自动携带Cookie的问题。首先,通过HttpClient获取登录页面的HTML内容,然后使用WebView加载这个HTML内容。示例代码如下:
public String getLoginPageHtml(String url) {
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse response = httpClient.execute(httpGet);
InputStream inputStream = response.getEntity().getContent();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line);
}
return stringBuilder.toString();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
2、 在获取到登录页面的HTML内容后,使用WebView加载这个HTML内容。示例代码如下:
WebView webView = findViewById(R.id.webView);
webView.loadData(getLoginPageHtml(url), "text/html; charset=utf-8", "UTF-8");
3、 在需要登录的地方,使用HttpClient模拟登录操作,获取Session ID和Cookie。示例代码如下:
public void login(String username, String password) {
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(loginUrl);
try {
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("username", username));
params.add(new BasicNameValuePair("password", password));
httpPost.setEntity(new UrlEncodedFormEntity(params));
HttpResponse response = httpClient.execute(httpPost);
InputStream inputStream = response.getEntity().getContent();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line);
}
// 解析返回的JSON数据,获取Session ID和Cookie
JSONObject jsonObject = new JSONObject(stringBuilder.toString());
String sessionId = jsonObject.getString("session_id");
String cookie = jsonObject.getString("cookie");
// 保存Session ID和Cookie到SharedPreferences
SharedPreferences sharedPreferences = getSharedPreferences("loginInfo", MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("session_id", sessionId);
editor.putString("cookie", cookie);
editor.apply();
} catch (IOException | JSONException e) {
e.printStackTrace();
}
}
private boolean isLogin() {
SharedPreferences sharedPreferences = getSharedPreferences("loginInfo", MODE_PRIVATE);
return sharedPreferences.contains("session_id") && sharedPreferences.contains("cookie");
}
public void goToFunction() {
if (isLogin()) {
// 已登录,直接跳转到教务系统功能页面
Intent intent = new Intent(this, FunctionActivity.class);
startActivity(intent);
} else {
// 未登录,调用登录方法进行登录操作
login(username, password);
}
}
通过以上方法,可以解决Android WebView绕过登录界面直接登录的问题。
如果以上回答对您有所帮助,点击一下采纳该答案~谢谢
问题可能是由于WebView的cookie管理机制导致的。WebView默认的cookie管理是与系统的CookieManager相关联的,多个WebView实例之间共享同一个CookieManager,这可能导致在不同WebView实例之间共享cookie,从而导致登录状态混乱。
可以尝试修改WebView的cookie管理,让每个WebView实例拥有独立的cookie存储,而不与系统的CookieManager共享。你可以通过重写WebViewClient的shouldOverrideUrlLoading方法,并在其中设置自定义的cookie:
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// 在加载每个URL之前,通过HttpClient获取最新的session id,
// 并将session id设置到WebView的cookie中
String sessionId = getNewSessionId();
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setCookie(url, "sessionId=" + sessionId);
return false;
}
});
其中,getNewSessionId方法可以使用HttpClient等工具获取最新的session id。
确保在重新加载或访问教务系统中的功能时不出现设备在其他地方登录的提示,你还可以尝试在每次WebView加载教务系统页面时,通过shouldOverrideUrlLoading方法拦截页面跳转,判断是否跳转到了登录页面,如果是,则重新加载个人信息主页,并设置新的session id。
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (isLoginPage(url)) {
// 重新加载个人信息主页,并设置新的session id
String sessionId = getNewSessionId();
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setCookie(personalInfoUrl, "sessionId=" + sessionId);
webView.loadUrl(personalInfoUrl);
return true;
}
return false;
}
});
其中,isLoginPage方法可以根据URL判断当前是否是登录页面。
通过以上方法设置独立的cookie管理和判断是否重新加载页面,你可以尝试解决登录状态混乱的问题。同时,确保在网络波动较大时功能运行正常的可能性增加。