session使用小结
最近做的Android客户端程序中通过HTTP请求和服务器通信,客户端程序需要做一个自动登录的功能,比如一个用户在一个Android手机登录后,退出游戏后在点击该游戏可以直接进入游戏。同时客户端发送的每一个请求都需要在服务器进行验证,来判断该请求是否是某个用户发来的,和同事思考了后决定用PHP 的session来做。当一个用户发送的3个请求A.B.C有并发顺序时,还可以利用session来控制处理ABC请求的顺序。
以前接触过J2EE方面的东西,session用的最多的还是来维持客户端和服务器端的一个通信,鉴于HTTP是一中无状态的协议,需要有一个机制来跟踪标识一个特定的用户(确切的来说是标识一个特定的客户端)。jsp提供了四种方法来跟踪客户的状态 1:建立匿名的表格字段 2: 使用url传递 3 使用持久化的cookies 4:使用session 的会话机制 ,相对于安全级别来说第四种最高了。Servlet可以很方便的在session范围内通过setAttribute和getAttribute来存取有用的信息,比如一个用户登录后,判断session并新建一个新的会话,将一个标识用户是否登录的值login存取session范围内,在前台的每个JSP页面都取出来判断,如果不为真则跳到登录界面。
session的实现在不同的语言中可能有所不同,比如PHP 和 Servlet中,但里面的机制应该差不多。以PHP为例,session这个东西是相对于服务器来说的,当服务器生成一个session时,服务器会生成一个唯一的sessionid来标示这个session,同时服务器会根据该Id开辟一个空间(比如一个文件)来存放些东西,这样我们就可以在session中放入我们的数据。服务器生成session后,会在响应的set-cookie中将该sessionid传到客户端,客户端收到该id后将其保存在客户端,在以后的每个请求中都将sessionid以cookie形式放入请求头中传入服务器,这样服务器就可以根据sessionid找到特定的session,从而存取数据进行操作。
PHP语言中在使用会话功能之前,必须开始一个会话。可以使用session_start()方法来开始一个会话。这个方法首先会判断当前是否有$_COOKIE[session_name()];session_name()返回保存session_id的COOKIE键值,这个值可以从php.ini找到 session.name = PHPSESSID //默认值PHPSESSID ,也就是说如果请求中的COOKIE里有PHPSESSID=xxxxxx时,表明有个会话ID存在,session_id = $_COOKIE[session_name]; 然后去session.save_path指定的文件夹里去找名字为'SESS_' . session_id()的文件。读取文件的内容反序列化,然后放到$_SESSION中。如果不存在一个会话ID,该函数就会生成一个session_id,然后把生成的session_id作为COOKIE的值传递到客户端。
当浏览器收到响应后,一般会把这个sessionid存下来,在以后的请求中自动带到cookie中发送到服务器。而在Android程序中服务器返回的响应中客户端并没有自动去读取,所以这需要自己去人工的读取并把它添加到发送的请求中。具体的代码如下:
这几行代码将服务器端返回的sessionid取出来,并存在sessionId变量中,然后客户端每次发送请求时都将这个sessionid带到服务器,同时也将用户的id也带过去,服务端验证这个请求是否某个用户发送过来的。具体代码如下:
这样客户端在以后的每一次请求中都将sessionid和userid放在cookie中一起发送到服务器。当客户端第一次收到响应中的sessionid时,读取后放在变量中,并且写入文件中。每次用户点击游戏图标时,就去读配置文件,如果sessionid有值,就跳过登录界面,直接进入游戏界面,然后发送请求将sessionid发送到服务器。客户端中有一个注销登录的功能,它主要发送一个请求给服务器,服务器收到后销毁用户的这个session,客户端这边也将保存sessionid的配置文件清空。下次点击游戏图标的时候就需要用户登录了。
服务器登录功能的代码如下:
session_start();
if (isset($_SESSION['userid'])) {
//用户会话已经存在,从会话中取出信息进行处理
$sourceid = $_SESSION['userid'];
......
} else {
//第一次登录的处理,取用户名密码信息处理,并将userid存入$_SESSION中
......
}
对于后续服务器接收到的请求,可以通过函数来判断这个请求是否合法有效,简单的判断方法就是将客户端带来的userid和服务器会话中保存的userid进行比较,如果一致就处理请求,如果不一致就认为客户端的请求有问题,可以做相应的处理。
session的用处还有很多,这次主要是用session来完善HTTP协议无状态的缺憾,关于session的许多其他功能还需在日后的工作学习中发掘应用。