VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > PHP >
  • php设置session值和cookies的学习示例

一直没弄懂Session,cookies什么的登陆验证到底是怎么回事,昨天分别用HttpURLConnection和HttpClient两个类来实验了一下,基本弄明白了Session验证登陆的机制和这两个类的区别。现在分享给大家。

第一步:先在本地写一个登陆页面和一个内容页面(登陆了才能进去)吧。代码大致如下:

下面是login.php,用于请求登陆的,通过post传递参数,如果登陆成功就会注册session,代码如下:

  1. <?php 
  2. session_start(); 
  3.  
  4. if (isset($_POST['username'])) { 
  5.     $username = $_POST['username']; 
  6.     $password = $_POST['password']; 
  7.  
  8.     if ($username == 'admin' && $password == 'admin') { 
  9.         $_SESSION['username'] = $username
  10.         echo "<a href='content.php'>进入网站</a>"
  11.     } else { 
  12.         echo "-1"
  13.     } 
  14. ?> 
  15. <html> 
  16. <body> 
  17. <form action="" method="post"
  18. <input type="text" name="username" /> 
  19. <input type="password" name="password" /> 
  20. <input type="submit" name="submit" value="submit" /> 
  21. </form> 
  22. </body> 
  23. </html> 

下面是content.php,会验证session,用来当网站的内容页,登陆了才能看到正确的内容,代码如下:

  1. <?php 
  2. session_start(); 
  3. if (isset($_SESSION['username'])) { 
  4.     echo "login ok"
  5. else { 
  6.     echo "not login"
  7. ?> 

接下来先讲HttpURLConnection这个类,先使用这个类直接请求content.php页面,理所应当的返回了"-1"。如果先用这个类去请求login.php,并传递正确的参数,就会显示登陆成功,这个时候再去用这个类请求content.php,依然是返回"-1",很显然,HttpURLConnection并没有记录我们登陆的状态,或者说服务器认识刚刚登陆成功的人,但这次请求content.php的人它依然不认识。这就说明了HttpURLConnection的每一次请求都是独立的,都是一次新的请求,或者说每一次请求都是一个新的会话(session)。

然后我就用chrome去开我自己写的那个测试的网页,发现在同一个网站下,同一次会话中,有一个sessionid是不会变的。

就是上面这个东西,如果开着某个页面,无论如何刷新,或者跳转到这个服务器下的其他网站,这个SESSIONID的值都不会改变,但是如果关掉这个服务器下的所有页面,再重新打开这样的一个页面,这个SESSIONID的值就被重新生成了。

于是用HttpURLConnection的情况,第一次登陆login.php是一个SESSIONID,确实登陆成功了,服务器记住的是SESSIONID为A的情况(假设是A好了),但再去请求content.php的时候,SESSIONID就不是A了,服务器就认为你没有登陆,于是就显示了“-1”。问题搞明白了,那么只需要在HttpURLConnection请求的时候,给它加上SESSIONID这个头部就行了。最终代码如下:

  1. public class NetHelper { 
  2.  
  3.     /** 
  4.      * SESSIONID 
  5.      * */ 
  6.     private String sessionId = ""
  7.  
  8.     /** 
  9.      * 发送一条请求,将内容以字符串返回 
  10.      * @param url 请求的地址 
  11.      * @return 返回的内容 
  12.      * */ 
  13.     public String request(String url) throws IOException { 
  14.         URL uUrl = new URL(url); 
  15.         HttpURLConnection huc = (HttpURLConnection) uUrl.openConnection(); 
  16.         huc.addRequestProperty("Cookie", sessionId);    //为什么是“Cookie”,Chrome打开F12自己看看就明白了 
  17.         huc.connect(); 
  18.         BufferedReader br = new BufferedReader(new InputStreamReader(huc.getInputStream())); 
  19.         String data = ""
  20.         String line = ""
  21.         while ((line = br.readLine()) != null) { 
  22.              data = data + line; 
  23.         } 
  24.         return data; 
  25.     } 
  26.  
  27.     /** 
  28.      * 发送登陆请求,并将SESSIONID保存起来 
  29.      * @param url 登陆请求的地址 
  30.      * @return 返回的内容 
  31.      * */ 
  32.     public String login(String url) throws IOException { 
  33.         URL uUrl = new URL(url); 
  34.         HttpURLConnection huc = (HttpURLConnection) uUrl.openConnection(); 
  35.  
  36.         //设置请求方式 
  37.         huc.setRequestMethod("POST"); 
  38.  
  39.         //设置post参数 
  40.         StringBuffer params = new StringBuffer(); 
  41.         params.append("username=").append("admin").append("&").append("password=").append("admin"); 
  42.         byte[] bytes = params.toString().getBytes(); 
  43.         huc.getOutputStream().write(bytes); 
  44.  
  45.         huc.connect(); 
  46.  
  47.         //从headers中取出来,并分割,为什么要分割,Chrome打开F12自己看看就明白了 
  48.         String[] aaa = huc.getHeaderField("Set-Cookie").split(";"); 
  49.         sessionId = aaa[0]; 
  50.  
  51.         BufferedReader br = new BufferedReader(new InputStreamReader(huc.getInputStream())); 
  52.         String data = ""
  53.         String line = ""
  54.         while ((line = br.readLine()) != null) { 
  55.              data = data + line; 
  56.         } 
  57.         return data; 
  58.     } 

接下来就是使用HttpClient,代码类似的,我做了相同的实验,结果就直接出来了,HttpClient会自动的管理Session,第二次请求不需要手动去设置Session就可以登录上,代码如下:

  1. public class NetClient { 
  2.  
  3.     private HttpClient client = null;  
  4.  
  5.     public NetClient() { 
  6.         client = new DefaultHttpClient(); 
  7.     } 
  8.  
  9.     public String request(String url) throws ClientProtocolException, IOException { 
  10.         HttpPost post = new HttpPost(url); 
  11.         HttpResponse res = client.execute(post); 
  12.  
  13.         BufferedReader br = new BufferedReader(new InputStreamReader(res.getEntity().getContent())); 
  14.         String data = ""
  15.         String line = ""
  16.         while ((line = br.readLine()) != null) { 
  17.              data = data + line; 
  18.         } 
  19.         return data; 
  20.     } 
  21.  
  22.     public String login(String url) throws ClientProtocolException, IOException { 
  23.         HttpPost post = new HttpPost(url); 
  24.  
  25.         //设置post参数的方式还真是不人性化啊…… 
  26.         ArrayList<NameValuePair> pa = new ArrayList<NameValuePair>(); 
  27.         pa.add( new BasicNameValuePair( "username""admin")); 
  28.         pa.add( new BasicNameValuePair( "password""admin")); 
  29.         post.setEntity( new UrlEncodedFormEntity(pa, "UTF-8")); 
  30.  
  31.         HttpResponse res = client.execute(post); 
  32.  
  33.         BufferedReader br = new BufferedReader(new InputStreamReader(res.getEntity().getContent())); 
  34.         String data = ""
  35.         String line = ""
  36.         while ((line = br.readLine()) != null) { 
  37.              data = data + line; 
  38.         } 
  39.         return data; 
  40.     } 

最后总结一下,Session验证的方式是在一次会话中,为每一个客户端都生成了一个SESSIONID,如果是成功登陆的,服务器端就会记录好,登陆成功的SESSIONID,如果登陆失败或者新的SESSIONID,都将无法验证登陆,这就是SESSION验证登陆的基本情况。

而HttpURLConnection和HttpClient这两个类都可以用来网络请求,但稍有不同,HttpuRLConnection每一次请求都是新的会话,如果需要去验证SESSIONID,就必须手动的去设置Header,HttpClient就能智能的管理Session,不需要手动设置,实际上HttpClint就类似于一个程序中的小浏览器。

最大的槽点我觉得就是这两个类设置post参数的方式都很2B一点都不方便……

另外HttpClient不能同时发送两次请求,如果一个请求还没有结束或者关闭,又马上开启另一个请求,就会报警告。

所以我综合考虑了下,以后还是尽量都使用HttpURLConnection吧。

出处:http://www.phpfensi.com/php/20201101/13385.html
 


相关教程