简介:
Session的概念在Android开发中遇到概率还是比较少,之前遇到一个项目的登陆接口返回不是Token,而且自己需要和服务端保持是Session,虽然这种情景很少,但是遇上的时候不懂一点后端知识就会导致不必要的沟通和降低效率。
在PHP开发偶尔会遇到需要保存Session数据到数据库的要求,大多也是为了实现Session共享,当然Session共享几乎不会出现在原生开发,基本都是出现在Web开发领域,自己简单的实践了PHP的自定义保存Session功能,用起来还是非常方便。
Android保持Session
现在Android开发基本都是用OkHttp了,这里介绍如何使用OkHttp实现Session保持。
开始之前先简介一下Cookie与Session的区别与联系:
1、Cookie储存在客户端,Session储存在服务器端,他们之间的概念相似,都是用于存储信息。
2、Session由SESSION_ID和相关键值对信息组成,SESSION_ID标识一个客户端。
2、Session是基于Cookie而实现的,把SESSION_ID通过Cookie储存在客户端。
3、每次请求时将SESSION_ID加入请求头中发送到服务端,从而匹配SESSION_ID所对应的Session信息
Http响应的Response Header中的Set-Cookie就是告诉客户端要设置cookie,cookie值是一个字符串,有特殊的格式:
一般的格式:Set-Cookie: <cookie-name>=<cookie-value>
更多格式参考:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Set-Cookie
一般我们使用浏览器的时候,cookie会自动存储起来,并在请求的时候自动加入到请求头中,所以网站中我们登陆了之后,刷新页面或者下次重新进入网站,依然能识别到我们的身份。
在移动端原生的开发环境中,大部分框架并不会自动把cookie保存起来,当然就不会把cookie自动加入到请求头中。
使用OkHttp取出Cookie并保存的示例代码:
@Override public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { Headers headers =response.headers(); //response为okhttp请求后的响应 List<String> cookies = headers.values("Set-Cookie"); if (cookies.size() > 0) { String session = cookies.get(0); // 保存cookie值,这里第一个Cookie就是SESSION_ID,根据实际情况调整 sessionid = session.substring(0, session.indexOf(";")); }
使用OkHttp把SESSION_ID回传服务器示例代码:
OkHttpClient okHttpClient = mHttp; Request.Builder request = new Request.Builder().url(url); // 把SESSION_ID回传服务器 request.addHeader("cookie", sessionid); Call call = okHttpClient.newCall(request.build()); Response response = call.execute();
PHP自定义保存Session数据
原型:
1.session_set_save_handler ( callable $open , callable $close , callable $read , callable $write , callable $destroy , callable $gc [, callable $create_sid [, callable $validate_sid [, callable $update_timestamp ]]] ) : bool
2.session_set_save_handler ( object $sessionhandler [, bool $register_shutdown = TRUE ] ) : bool
实践:
1.调用session_start()之后,就会执行open → read → write → close
2.write是PHP脚本执行完毕之后调用的,就是保存当前Session的数据
3.read就是相当于恢复Session数据,一次性读入到$_SESSION变量中
实例:
class FileSessionHandler { private $savePath; function open($savePath, $sessionName) { echo __FUNCTION__."<BR>"; return true; } function close() { echo __FUNCTION__."<BR>"; return true; } function read($id) { echo __FUNCTION__."<BR>"; return ""; } function write($id, $data) { echo __FUNCTION__."<BR>"; return true; } function destroy($id) { echo __FUNCTION__."<BR>"; return true; } function gc($maxlifetime) { echo __FUNCTION__."<BR>"; return true; } function end(){ echo '我是最后脚本结束register_shutdown_functiond调用'."<br>"; } } $handler = new FileSessionHandler(); session_set_save_handler( array($handler, 'open'), array($handler, 'close'), array($handler, 'read'), array($handler, 'write'), array($handler, 'destroy'), array($handler, 'gc') ); // 下面这行代码可以防止使用对象作为会话保存管理器时可能引发的非预期行为 register_shutdown_function(array($handler, "end")); session_start();
以上代码执行输出如下:
open read 脚本执行结束 write close
Session数据的格式
在read函数的返回值和write函数中的data参数中,都是全部Session数据的字符串,格式是这样:
age|i:18;name|s:5:"Jerry";
age和name分别是两个Session变量,如果在read函数中返回上面的字符串数据,通过$_SEESION["age"]、$_SEESION["name"]可以读取到。
所以就是说我们可以在read函数中,人为地增加任何Session数据,不过这样做并没有什么实际用途。