原理

本质是保存对话信息,给客户端一个唯一标识,然后在服务端存储相应的数据。

最简单的demo—session的基本用法

1 分配id

session_start();//使用这个函数 会为对话生成一个默认的标识id

这是我们访问对应的接口,并且打开控制台网络,可以在响应头中看到:

Set-Cookie: PHPSESSID=q10mlsnd8ve2393vstrc3qrjoq; path=/

此时,php只是给客户端默认分配了一个phpsession的唯一标识,服务端是没有存储这个的。(redis方式没存 文件存储方式还没验证)
客户端会把这个值存成cookie,下次请求的时候,客户端就会带上这个cookie。于是,服务端就知道谁是谁了。
ps:

  • 浏览器可自主更改设置sessionid,即使是不存在的sessionid,服务端不能意识到这个sessionid是之前不存在的……
  • ps:sessionid的生成应该与时间戳有关 所以较方便的能保证唯一性。但是多台机器+高并发的情况下,可能出现问题?所以得加个token 也能防止用户仿造。

  • sessionid的生成 不需要查本地是否有冲突。而是直接生成的 所以应该不会造成很大性能浪费。(有空验证下文件有没有 redis是只有存了数据才会有)

2 设置数据

$_SESSION['A'] = 1;//
session_start();//当session存在的时候 会读取这个sessionid下所有的值到内存中
$_SESSION['A'] = 1;


可以在redis中看到这个数据。

3 读取数据

echo $_SESSION['A'];//读取不到
session_start();//当客户端传过来的cookie有id时候 会去找值;cookie中没有id的时候,会生成一个id
echo $_SESSION['A'];

4 session_unset 与session_destory

session_unset()使用后 会清除掉这个session中的值,但是保留这个session_id(别人不能使用)

session_destory则会删除这个session的值和这个sessionid本身。但是本次对话中加载的session不会清除,也就是说你使用destory后 本次对话还能用$_session[‘xxx’]获取到对应的值。但是本地http对话结束后就再也访问不到了

5 session_id()

用这个可以手动指定sessionid,然后session_start()即可。这个必须在session_start前使用!所以 要使用这个功能,必须先关闭ini的session auto_start
如果用户传过来的cookie中本身有sessionid,那么你用session_id()新设置的会覆盖掉用户设置的,而且返回头中会多一个set-cookie(你新设置的id)

需要配置php.ini 或者ini函数设置(推荐后者)

修改方式

1、修改ini文件

1.1、获取ini文件的位置

echo phpinfo()

2.2、修改php.ini文件 记得更改完要重启php!(fpm还是php?)

  1. 设置session不会自动开启,即session.auto_start = 0

  2. 允许跨页传输 use_trans_sid=1 以及’use_only_cookies’=0

PHP中的session在默认情况下是使用客户端的Cookie来保存session id的,所以当客户端的cookie出现问题的时候就会影响session了。必须注意的是:session不一定必须依赖cookie,这也是session相比cookie的高明之处。当客户端的Cookie被禁用或出现问题时,PHP会自动把session id附着在URL中,这样再通过session id就能跨页使用session变量了。但这种附着也是有一定条件的,即“php.ini中的session.use_trans_sid = 1或者编译时打开打开了–enable-trans-sid选项”。

  1. 确认ini中存储session的目录 session.save_path

如果那个目录不行就换一个 windows下如D:\phpstudy_pro\Extensions\tmp\tmp Linux下/tmp 代表根目录下的tmp文件夹 注意:如果那个文件夹不存在 可能要手动创建 而且要检查文件夹权限 而且要注意可能是所有者的问题

2、ini_set修改

        $redis_config = config_item('REDIS_CONFIG');$redis_config = $redis_config['read']??'';$host = $redis_config['host']??'';$port = $redis_config['port']??'';$auth = $redis_config['auth']??'';if(empty($host)||empty($port)||empty($auth)) return false;$redis_url = "tcp://".$host.":".$port."?auth=". $auth;ini_set("session.save_handler", "redis");ini_set("session.save_path", $redis_url);ini_set('session.serialize_handler', 'php_serialize');ini_set('session.name', '你自己取一个');ini_set('session.cookie_domain', '.360.cn');ini_set('session.cookie_httponly', 1);ini_set('session.cookie_secure', 1);ini_set('session.cookie_lifetime', 365 * 86400);

一些设置项说明

生存时间

gc_maxlifetime 不是在你设置session的地方弄 而是在你访问的地方去判断
如果在你设置的地方判断 则小于等于6秒 好像是php真正退出当前对话的时候 会gc 然后销毁 再往后就只能访问session的地方去判断gc了

session.gc_maxlifetime:session的有效生存时间,过了这个时间session将进入销毁队列。过了这个时间并不能马上销毁,这又涉及到session.gc_probability和session.gc_divisor,这两个参数决定超过gc.maxlifetime的session被销毁的概率,只有session被销毁才能算过期。

session.cookie_lifetime:值为0代表关闭浏览器,保存在客户端的sessionid将立即失效(客户端自动删除这个cookie)

还有session比较糟糕的是他没有像cookie那样默认就有域的隔离,如果你没做session.path的设置,那么运行在同一个服务器上的不同项目session文件是存在同一个目录的,不同项目的对maxlifetime的配置就会相互影响,gc的垃圾回收机制会按照后来者的配置值进行删除,前者的设置无效了。

session_destory可以立即销毁session!

//双管齐下来了一个双保险,即对session.gc_maxlifetime和session.cookie_lifetime的设置,同时主动对会话过期时间做判断。
//如果gc没有回收过期的session,那么程序中会话过期判断就会进行补刀。
public function __construct(){parent::__construct();if(!session('adminId')){$this->redirect(U('Admin/Login/index'));};//判断会话是否过期if (time() - session('session_start_time') > C('SESSION_OPTIONS')['expire']) {session_destroy();//真正的销毁在这里!$this->redirect(U('Admin/Login/index'));}}

一个已知管用的方法是,使用session_set_save_handler,接管所有的session管理工作,一般是把session信息存储到数据库,这样可以通过SQL语句来删除所有过期的session,精确地控制session的有效期。这也是基于PHP的大型网站常用的方法。但是,一般的小型网站,没有资源这么浪费。

下面我们来说说怎么实现session永久生命周期,一般的Session的生命期是有限的,如果用户关闭了浏览器,就不能保存Session的变量了!

在服务器端储存Session,根据客户端提供的SessionID来得到这个用户的文件,然后读取文件,取得变量的值,SessionID可以使用客户端的Cookie或者Http1.1协议的Query_String(就是访问的URL的“?”后面的部分)来传送给服务器,然后服务器读取Session的目录……
如果想要 Session的生命期成为永久,需要了解一下php.ini关于Session的相关设置,在php.ini中搜索底下的关键字:
1、session.use_cookies:默认的值是“1”,代表SessionID使用Cookie来传递,反之就是使用Query_String来传递;

2、session.name:这个就是SessionID储存的变量名称,可能是Cookie,也可能是Query_String来传递,默认值是“PHPSESSID”;

3、session.cookie_lifetime:这个代表SessionID在客户端Cookie储存的时间,默认是0,代表浏览器一关闭SessionID就作废……就是因为这个所以Session不能永久使用!

4、session.gc_maxlifetime:这个是Session数据在服务器端储存的时间,如果超过这个时间,那么Session数据就自动删除!

还有很多的设置,不过和本文相关的就是这些了,下面开始讲使用永久Session的原理和步骤。
前面说过,服务器通过SessionID来读取Session的数据,但是一般浏览器传送的SessionID在浏览器关闭后就没有了,那么我们只需要人为的设置SessionID并且保存下来,不就可以……
如果你拥有服务器的操作权限,那么设置这个非常非常的简单,只是需要进行如下的步骤:
1、把“session.use_cookies”设置为1,打开Cookie储存SessionID,不过默认就是1,一般不用修改;
2、把“session.cookie_lifetime”改为正无穷(当然没有正无穷的参数,不过999999999和正无穷也没有什么区别);
3、把“session.gc_maxlifetime”设置为和“session.cookie_lifetime”一样的时间;
在PHP的文档中明确指出,设定session有效期的参数是session.gc_maxlifetime。可以在php.ini文件中,或者通过ini_set()函数来修改这一参数。问题在于,经过多次测试,修改这个参数基本不起作用,session有效期仍然保持24分钟的默认值。
由于PHP的工作机制,它并没有一个daemon线程,来定时地扫描session信息并判断其是否失效。当一个有效请求发生时,PHP会根据全局变量session.gc_probability/session.gc_divisor(同样可以通过php.ini或者ini_set()函数来修改)的值,来决定是否启动一个GC(Garbage Collector)。
默认情况下,session.gc_probability = 1,session.gc_divisor =100,也就是说有1%的可能性会启动GC。GC的工作,就是扫描所有的session信息,用当前时间减去session的最后修改时间(modified date),同session.gc_maxlifetime参数进行比较,如果生存时间已经超过gc_maxlifetime,就把该session删除。
到此为止,工作一切正常。那为什么会发生gc_maxlifetime无效的情况呢?
在默认情况下,session信息会以文本文件的形式,被保存在系统的临时文件目录中。在Linux下,这一路径通常为\tmp,在 Windows下通常为C:\Windows\Temp。当服务器上有多个PHP应用时,它们会把自己的session文件都保存在同一个目录中。同样地,这些PHP应用也会按一定机率启动GC,扫描所有的session文件。
问题在于,GC在工作时,并不会区分不同站点的session。举例言之,站点A的gc_maxlifetime设置为2小时,站点B的 gc_maxlifetime设置为默认的24分钟。当站点B的GC启动时,它会扫描公用的临时文件目录,把所有超过24分钟的session文件全部删除掉,而不管它们来自于站点A或B。这样,站点A的gc_maxlifetime设置就形同虚设了。
找到问题所在,解决起来就很简单了。修改session.save_path参数,或者使用session_save_path()函数,把保存session的目录指向一个专用的目录,gc_maxlifetime参数工作正常了。
严格地来说,这算是PHP的一个bug?
还有一个问题就是,gc_maxlifetime只能保证session生存的最短时间,并不能够保存在超过这一时间之后session信息立即会得到删除。因为GC是按机率启动的,可能在某一个长时间内都没有被启动,那么大量的session在超过gc_maxlifetime以后仍然会有效。
解决这个问题的一个方法是,把session.gc_probability/session.gc_divisor的机率提高,(谨慎设置,性能消耗严重,通常有高并发的需求的话,设置在1/1000为好)如果提到100%,就会彻底解决这个问题,但显然会对性能造成严重的影响。另一个方法是自己在代码中判断当前session的生存时间,如果超出了 gc_maxlifetime,就清空当前session。
————————————————
版权声明:本文为CSDN博主「Su RuiN」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_39999924/article/details/120825341

path

path的作用是隔离?

handler

other

-cookie如此重要,在浏览器端,如果一个网站可以访问其他网站的cookie,肯定不行的,所以浏览器是不允许跨域访问cookie的,提高了Cookie的安全性。

在前面的文章 session和cookie介绍 中,已经介绍了cookie的作用域,主要是说一级域名相同情况下如何共享使用cookie。

如果想实现跨域访问,可以通过JSONP、CORS的方法实现。

另外,HTTP设置cookie时,提供了2个属性,可以增强cookie的安全性,分别是secure属性和httpOnly属性。

secure属性可防止信息在传递的过程中被监听捕获后导致信息泄露,如果设置为true,可以限制只有通过https访问时,才会将浏览器保存的cookie传递到服务端,如果通过http访问,不会传递cookie。

httpOnly属性可以防止程序获取cookie,如果设置为true,通过js等将无法读取到cookie,能有效的防止XSS攻击。

可能遇到的坑

1、框架中可能单独对session设置,造成修改php.ini或者你的代码无效

比如thinkphp3.2可看: https://www.cnblogs.com/dee0912/p/5061053.html
ps、thinkphp3 如果要修改使用redis存储,需要修改源码。修改方法看后面

2、微信小程序–需要微信服务器中转以及不支持cookie

不支持cookie的解决方法:手动存下来cookie即可;
中转的解决方法:(正常写法都不会出问题 不用看了 除非遇到问题)
由于小程序端传给服务器的数据不是直接传输的,中间还要经过微信官方的服务器,所以可以在服务器文件中增加一条判断条件(直接复制可能不对 因为word中会有奇奇怪怪的空格符号或者格式等)

session_start();
$iid = $_POST['sessionid'];
if($iid != session_id()) session_destroy();
session_id($iid);
session_start();

似乎现在先设置 也可以了

session_id('4tt7i96ifce168fq5qqq1encar');
session_start();

或者将sessionid直接写在header头中,参考:
https://blog.csdn.net/weixin_30667301/article/details/97883820
https://www.jianshu.com/p/d580fbee1e3a
http://www.cocoachina.com/articles/33781

3、nginx的设置可能也会影响

附录-thinkphp3.2修改redis存session的方法

ThinkPHP/Common/functions.php 新增这个函数

/*** session管理函数* @param string|array $name session名称 如果为数组则表示进行session设置* @param mixed $value session值* @return mixed*/
function session($name='',$value='') {$prefix   =  C('SESSION_PREFIX');if(is_array($name)) { // session初始化 在session_start 之前调用if(isset($name['prefix'])) C('SESSION_PREFIX',$name['prefix']);if(C('VAR_SESSION_ID') && isset($_REQUEST[C('VAR_SESSION_ID')])){session_id($_REQUEST[C('VAR_SESSION_ID')]);}elseif(isset($name['id'])) {session_id($name['id']);}if('common' == APP_MODE){ // 其它模式可能不支持ini_set('session.auto_start', 0);}if(isset($name['name']))            session_name($name['name']);if(isset($name['path']))            session_save_path($name['path']);if(isset($name['domain']))          ini_set('session.cookie_domain', $name['domain']);if(isset($name['expire']))          {ini_set('session.gc_maxlifetime',   $name['expire']);ini_set('session.cookie_lifetime',  $name['expire']);}if(isset($name['use_trans_sid']))   ini_set('session.use_trans_sid', $name['use_trans_sid']?1:0);if(isset($name['use_cookies']))     ini_set('session.use_cookies', $name['use_cookies']?1:0);if(isset($name['cache_limiter']))   session_cache_limiter($name['cache_limiter']);if(isset($name['cache_expire']))    session_cache_expire($name['cache_expire']);if(isset($name['type']))            C('SESSION_TYPE',$name['type']);if(C('SESSION_TYPE')) { // 读取session驱动$type   =   C('SESSION_TYPE');$class  =   strpos($type,'\\')? $type : 'Think\\Session\\Driver\\'. ucwords(strtolower($type));$hander =   new $class();session_set_save_handler(array(&$hander,"open"),array(&$hander,"close"),array(&$hander,"read"),array(&$hander,"write"),array(&$hander,"destroy"),array(&$hander,"gc"));}// 启动sessionif(C('SESSION_AUTO_START'))  session_start();}elseif('' === $value){if(''===$name){// 获取全部的sessionreturn $prefix ? $_SESSION[$prefix] : $_SESSION;}elseif(0===strpos($name,'[')) { // session 操作if('[pause]'==$name){ // 暂停sessionsession_write_close();}elseif('[start]'==$name){ // 启动sessionsession_start();}elseif('[destroy]'==$name){ // 销毁session$_SESSION =  array();session_unset();session_destroy();}elseif('[regenerate]'==$name){ // 重新生成idsession_regenerate_id();}}elseif(0===strpos($name,'?')){ // 检查session$name   =  substr($name,1);if(strpos($name,'.')){ // 支持数组list($name1,$name2) =   explode('.',$name);return $prefix?isset($_SESSION[$prefix][$name1][$name2]):isset($_SESSION[$name1][$name2]);}else{return $prefix?isset($_SESSION[$prefix][$name]):isset($_SESSION[$name]);}}elseif(is_null($name)){ // 清空sessionif($prefix) {unset($_SESSION[$prefix]);}else{$_SESSION = array();}}elseif($prefix){ // 获取sessionif(strpos($name,'.')){list($name1,$name2) =   explode('.',$name);return isset($_SESSION[$prefix][$name1][$name2])?$_SESSION[$prefix][$name1][$name2]:null; }else{return isset($_SESSION[$prefix][$name])?$_SESSION[$prefix][$name]:null;               }           }else{if(strpos($name,'.')){list($name1,$name2) =   explode('.',$name);return isset($_SESSION[$name1][$name2])?$_SESSION[$name1][$name2]:null; }else{return isset($_SESSION[$name])?$_SESSION[$name]:null;}           }}elseif(is_null($value)){ // 删除sessionif(strpos($name,'.')){list($name1,$name2) =   explode('.',$name);if($prefix){unset($_SESSION[$prefix][$name1][$name2]);}else{unset($_SESSION[$name1][$name2]);}}else{if($prefix){unset($_SESSION[$prefix][$name]);}else{unset($_SESSION[$name]);}}}else{ // 设置sessionif(strpos($name,'.')){list($name1,$name2) =   explode('.',$name);if($prefix){$_SESSION[$prefix][$name1][$name2]   =  $value;}else{$_SESSION[$name1][$name2]  =  $value;}}else{if($prefix){$_SESSION[$prefix][$name]   =  $value;}else{$_SESSION[$name]  =  $value;}}}return null;
}

加一个redis的驱动文件,ThinkPHP/Library/Think/Session/Driver/Redis.class.php

<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
namespace Think\Session\Driver;use think\Exception;class Redis implements \SessionHandlerInterface
{/** @var \Redis */protected $handler = null;protected $config = [// redis主机'host' => '127.0.0.1',// redis端口'port' => 6379,// 密码'password' => 123456',// 操作库'select' => 1,// 有效期(秒)'expire' => 3600,// 超时时间(秒)'timeout' => 0,// 是否长连接'persistent' => true,// sessionkey前缀'session_name' => 'session_',];public function __construct($config = []){$this->config['host'] = C("SESSION_REDIS_HOST") ? C("SESSION_REDIS_HOST") : $this->config['host'];$this->config['port'] = C("SESSION_REDIS_POST") ? C("SESSION_REDIS_POST") : $this->config['port'];$this->config['password'] = C("SESSION_REDIS_AUTH") ? C("SESSION_REDIS_AUTH") : $this->config['password'];$this->config['select'] = C("SESSION_REDIS_SELECT") ? C("SESSION_REDIS_SELECT") : $this->config['select'];$this->config['expire'] = C("SESSION_REDIS_EXPIRE") ? C("SESSION_REDIS_EXPIRE") : $this->config['expire'];$this->config['session_name'] = C('SESSION_PREFIX') ? C('SESSION_PREFIX') : $this->config['session_name'];$this->config['timeout'] = C('SESSION_CACHE_TIMEOUT') ? C('SESSION_CACHE_TIMEOUT') : $this->config['timeout'];}/*** 打开Session* @access public* @param string $savePath* @param mixed $sessName* @return bool* @throws Exception*/public function open($savePath, $sessName){// 检测php环境if (!extension_loaded('redis')) {throw new Exception('not support:redis');}$this->handler = new \Redis;// 建立连接$func = $this->config['persistent'] ? 'pconnect' : 'connect';$this->handler->$func($this->config['host'], $this->config['port'], $this->config['timeout']);if ('' != $this->config['password']) {$this->handler->auth($this->config['password']);}if (0 != $this->config['select']) {$this->handler->select($this->config['select']);}return true;}/*** 关闭Session* @access public*/public function close(){$this->gc(ini_get('session.gc_maxlifetime'));$this->handler->close();$this->handler = null;return true;}/*** 读取Session* @access public* @param string $sessID* @return string*/public function read($sessID){return (string)$this->handler->get($this->config['session_name'] . $sessID);}/*** 写入Session* @access public* @param string $sessID* @param String $sessData* @return bool*/public function write($sessID, $sessData){if ($this->config['expire'] > 0) {return $this->handler->setex($this->config['session_name'] . $sessID, $this->config['expire'], $sessData);} else {return $this->handler->set($this->config['session_name'] . $sessID, $sessData);}}/*** 删除Session* @access public* @param string $sessID* @return bool*/public function destroy($sessID){return $this->handler->delete($this->config['session_name'] . $sessID) > 0;}/*** Session 垃圾回收* @access public* @param string $sessMaxLifeTime* @return bool*/public function gc($sessMaxLifeTime){return true;}
}

最后,config中配置下就行

/* SESSION设置 begin*///初始化 session 配置数组 支持type name id path expire domain 等参数'SESSION_OPTIONS'       =>  array('type'=>'Redis','prefix'=>'sess_','path'=>'tcp://127.0.0.1:6379?auth=123456','expire'=>3600,),'SESSION_AUTO_START'    =>  true,    // 是否自动开启Session'SESSION_TYPE'          =>  'Redis', // session hander类型 默认无需设置 除非扩展了session hander驱动'SESSION_PREFIX'        =>  'sess_', // session 前缀'VAR_SESSION_ID'        =>  'session_id', //sessionID的提交变量//begin'SESSION_PERSISTENT'    =>  1,//是否长连接(对于php来说0和1都一样)'SESSION_CACHE_TIMEOUT' =>  3,//连接超时时间(秒)'SESSION_REDIS_EXPIRE'  =>  3600,        //session有效期(单位:秒) 0表示永久缓存'SESSION_REDIS_HOST'    =>  '127.0.0.1', //redis服务器ip'SESSION_REDIS_PORT'    =>  '6379',       //端口'SESSION_REDIS_AUTH'    =>  '123456', //认证密码'SESSION_REDIS_SELECT'  =>  '1',  //操作库//end/* SESSION设置 end*/

Other

PHP设置会话(Session)超时过期时间实现登录时间限制

最近某个PHP项目用到了限制登录时间的功能,比如用户登录系统60分钟后如果没有操作就自动退出,我搜索了网络收集了有以下方法可供参考。

第一种方法即设置php.ini配置文件,设置session.gc_maxlifetime和session.cookie_lifetime节点属性值,当然也可以使用ini_set函数改变当前上下文环境的属性值:

ini_set(‘session.gc_maxlifetime’, “3600”); // 秒

ini_set(“session.cookie_lifetime”,“3600”); // 秒
第二种方法即设置Session时间戳,比如下面的办法。

在登录成功时设置时间戳为当前时间推后1小时,$_SESSION[‘expiretime’] = time() + 3600;。在检查用户登录情况使用如下代码:

if(isset($_SESSION['expiretime'])) {  if($_SESSION['expiretime'] < time()) {  unset($_SESSION['expiretime']);  header('Location: logout.php?TIMEOUT'); // 登出  exit(0);  } else {  $_SESSION['expiretime'] = time() + 3600; // 刷新时间戳  }
}

https://www.jb51.net/article/52309.htm

不能同时设置两次session

不然会报错 比如你设置一个小程序的 一个其他服务的 前缀不同 但是不可

setcookie的

不能一个函数设置多个cookie
只能分开设置
发送的时候 request_header不会自动覆盖前面的set-cookie。但是浏览器会做处理 后面的会覆盖前面的,但是如果你是微信小程序中处理,则会有问题 不会自动覆盖

微信小程序中set-cookie的拼接方式有问题

微信小程序拼接是逗号,正常是分号
而且,为什么苹果手机、部分安卓手机没有问题?没有问题的Cookie,JESSIONID可以被后台正确分割出来。苹果手机获取Set-Cookie顺序是严格一致的,安卓手机Set-Cookie顺序是随机的。

解决方法,正则分割。(如果遇到domain等,其实小程序可以直接不管,因为浏览器会自动做 但是小程序不会啊 所以那些其实对小程序没啥用 得自己处理)


// 登录wx.login({success: function (res) {log.info(res)//获取登录的临时凭证var code = res.code;//调用后端,获取微信的session_key,secretwx.request({url: domain + '/user/wxLogin',header: {"Content-Type": "application/x-www-form-urlencoded"},method: "POST",data: util.json2Form({code: code,appId: that.globalData.appId}),success: function (result) {// Set-Cookie字符串获取var cookie = result.header['Set-Cookie']// 字符串分割成数组var cookieArray = cookie.split(/,(?=[^,]*=)/)// 分号拼接数组var newCookie = cookieArray.join(';')// 存储拼接后的cookietry {wx.setStorageSync('cookie', newCookie)} catch (error) {log.error('setStorageSync cookie fail')}},fail: function (res) {}})}})

sessionid和logintoken的时机问题

当登录失效的时候,
1 前端带着失效之前的cookie和logintoken
1.1 访问【其他接口】服务器种了个没有login_token的新cookie过来
1.2 访问【登录接口】,服务器只返回了login_token 没返回cookie

之后再访问其他的
2.1 前端访问其他接口,只剩下cookie了 没有login_token ,提示未登录
2.2 前端访问登录接口,只有一个login_token

解决方案 cookie必返回

echo session_id().PHP_EOL;//无数据$redis_config = config_item('WX_MINIPROGRAM_RDS');$redis_config = $redis_config['read']??'';$host = $redis_config['host']??'';$port = $redis_config['port']??'';$auth = $redis_config['auth']??'';if(empty($host)||empty($port)||empty($auth)) return false;$redis_url = "tcp://".$host.":".$port."?auth=". $auth;ini_set("session.save_handler", "redis");ini_set("session.save_path", $redis_url);ini_set('session.name', 'aaa');session_start();$_SESSION['a'] = 1;echo session_id(); //有数据

session详解--以php为例相关推荐

  1. JavaWeb 入门篇 (5) Cookie 和 Session 详解

    Cookie 和 Session 详解 一.会话的概念 会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话. 有状态会话:一个同学来过 ...

  2. java 登录session_JavaWeb Session详解

    记得把这几点描述好咯:代码实现过程 + 项目文件结构截图 + ## Session的由来 上一篇博文介绍了Cookie的相关知识,其中介绍了必须采用一种机制来唯一标识一个用户,同时记录该用户的状态. ...

  3. cookie 和 session 详解

    cookie 和 session 详解 文章目录 cookie 和 session 详解 一.Cookie机制 1.Cookie引入 2.什么是Cookie 3.Cookie的不可跨域名性 4. Un ...

  4. cookie与session详解、url地址重写

    cookie与session详解.url地址重写:https://www.cnblogs.com/l199616j/p/11195667.html

  5. Swift - SwiftyJSON的使用详解(附样例,用于JSON数据处理)

    转自:http://www.hangge.com/blog/cache/detail_968.html Swift - SwiftyJSON的使用详解(附样例,用于JSON数据处理) 2016-01- ...

  6. Matlab v_melcepst函数参数详解(英文附例)

    Matlab v_melcepst函数参数详解(英文附例) 笔者使用的是R2019的matlab,下载了voicebox安装至matlab路径下即可使用.下载voicebox请参看此博客 需要注意的是 ...

  7. matlab melbankm,Matlab v_melbankm函数参数详解(英文附例)

    Matlab v_melbankm函数参数详解(英文附例) 笔者使用的是R2019的matlab,下载了voicebox安装至matlab路径下即可使用.下载voicebox请参看此博客 需要注意的是 ...

  8. Hibernate - SessionFactory和Session详解

    [1]SessionFactory 接口 SessionFactory 接口是针对单个数据库映射关系经过编译后的内存镜像,是线程安全的. SessionFactory 对象一旦构造完毕,即被赋予特定的 ...

  9. Session详解,学习Session,这篇文章就够了(包含底层分析和使用)

    说明:下面介绍session,我们使用到了游览器抓包,http的知识,如果不了解,请先简单了解下.http介绍,http请求,http响应.因为cookie和session是一对"好兄弟&q ...

最新文章

  1. [裴礼文数学分析中的典型问题与方法习题参考解答]4.3.13
  2. faceapp怎么合成未来宝宝照片_宝宝出生后,爸爸们应该如何宣布喜讯,各种官宣文案孕妈赶紧收藏...
  3. 采用推理的方法认知单词、CBOW模型
  4. HeadFirst设计模式之观察者模式学习
  5. oracle 11g sga max,oracle 10g 11g中的SGA_MAX_SIZE与SGA_TARGET参数
  6. mysql front 视图_mysql 视图
  7. 46. 求1+2+3+...+n(C++实现)
  8. GALGAME 剧本提取工具
  9. C#中的线程(三)多线程
  10. HFSS 天线设计流程概述-截图
  11. SQL数据库注入防范 ASP.NET Globle警告
  12. 易语言服务器中转,让自己的电脑变成服务器,易语言远程文件传输器
  13. 【Junit Experiment】Junit 软件质量测试实验--日期格式规范性+字符串格式规范性
  14. 大数据小项目之电视收视率企业项目10
  15. 小米联合金山云发布“1KM边缘计算” 携手布局“云+边缘”新赛道
  16. Android自定义键盘
  17. ajax deferred 用法
  18. 如何上好大学计算机基础,如何学好大学计算机基础
  19. 实名推荐的神器,你安排上了几款?
  20. javascript高级程序设计读书笔记----引用类型

热门文章

  1. libuv 在win10 vs各个版本编译静态库
  2. 街霸对决最新服务器机柜销售,街霸对决100连抽兑换码分享 最新周杰伦定制礼包码汇总[多图]...
  3. PAT 1025 PAT Rankings 思路与题解
  4. Python实验之基于数据类型的应用
  5. WebUploader大文件上传解决方案
  6. sohu读博:鱼顺顺
  7. 不懂怎么给视频加水印?给视频加水印你可以这样做
  8. 【Web服务器】Apache网页优化
  9. 【黄啊码】MySQL入门—15、技术老大:写的SQL性能这么差,还好意思说自己五年开发经验?
  10. 大一作业HTML电影网页作业(HTML+CSS)