同一個(gè)文件里:
我在A方法里,
$session = $request->session();
$session->set('session_key', $result['session_key']);
// $session_key = $session->get('session_key');
并且打印 $session_key 確認(rèn)保存了。
我在B方法里:
$session = $request->session();
$session_key = $session->get('session_key');
$has = $session->has('session_key');
打印 $session_key 是 null , 打印 $has 是 false 。
為啥??
發(fā)一個(gè)能復(fù)現(xiàn)問(wèn)題的完整代碼和步驟
老大,這個(gè)貌似跟前端沒(méi)關(guān)系,因?yàn)榍岸蝹鱟ode 過(guò)來(lái),我從微信獲取的數(shù)據(jù),我打印是確定有session_key , 然后我才存到 session 里的。或者老大您告訴我應(yīng)該咋解決,我菜鳥(niǎo)一枚!
session是依賴(lài)cookie實(shí)現(xiàn)的,瀏覽器每次請(qǐng)求會(huì)帶上cookie,服務(wù)端就從cookie中得到session id,然后從磁盤(pán)或者redis找對(duì)應(yīng)session id的文件或數(shù)據(jù),才能還原上次記錄的session
// 同一個(gè)文件的 方法 A :
public function code2session(Request $request){
$param = [
'code' => $request->input('code'),
];
// 進(jìn)行參數(shù)校驗(yàn)
$validate = new Code2SessionValidate();
if (!$validate->check($param)) {
return json($validate->getError());
}
$app = Factory::miniProgram(config('myconfig.wechat.config'));
$result = $app->auth->session($param['code']);
if (array_key_exists('openid', $result) && array_key_exists('session_key', $result)) {
$key = 'openid:'.$result['openid'];
$isExists = Redis::exists($key);
if (!$isExists) {
$fields = [
'openid' => $result['openid'],
'session_key' => $result['session_key'],
];
Redis::hMSet($key, $fields);
}
$session = $request->session();
$session->set('session_key', $result['session_key']); // 我確定 $result['session_key'] 有值
} else {
return json([
'code' => config('myconfig.statusCode.HTTP_FAIL')[0],
'msg' => config('myconfig.statusCode.HTTP_FAIL')[1],
'data' => $result,
]);
}
return json([
'code' => config('myconfig.statusCode.HTTP_OK')[0],
'msg' => config('myconfig.statusCode.HTTP_OK')[1],
'data' => $result,
]);
// 同一個(gè)文件的 方法B:
public function getPhoneNumber(Request $request)
{
$param = [
'openid' => $request->input('openid'),
'encryptedData' => $request->input('encryptedData'),
'iv' => $request->input('iv'),
];
// 進(jìn)行參數(shù)校驗(yàn)
$validate = new GetPhoneNumberValidate();
if (!$validate->check($param)) {
return json($validate->getError());
}
$app = Factory::miniProgram(config('myconfig.wechat.config'));
$session = $request->session();
$session_key = $session->get('session_key'); // null
$all = $session->all(); // 空數(shù)組
$has = $session->has('session_key'); // false
$key = 'openid:'.$param['openid'];
$redis_value = Redis::hGetAll($key);
$result = $app->encryptor->decryptData($redis_value['session_key'], $param['iv'], $param['encryptedData']);
if (array_key_exists('purePhoneNumber', $result)){
// 設(shè)置哈希表的多個(gè)字段和值
$fields = [
'openid' => $redis_value['openid'],
'session_key' => $redis_value['session_key'],
'countryCode' => $result['countryCode'],
'purePhoneNumber' => $result['purePhoneNumber'],
];
// 將字段和對(duì)應(yīng)的值同時(shí)設(shè)置到哈希表中
Redis::hMSet($key, $fields);
$res['countryCode'] = $result['countryCode'];
$res['purePhoneNumber'] = $result['purePhoneNumber'];
}else{
return json([
// 'HTTP_FAIL' => [200110, '請(qǐng)求失敗'],
'code' => config('myconfig.statusCode.HTTP_FAIL')[0],
'msg' => config('myconfig.statusCode.HTTP_FAIL')[1],
'data' => $result,
]);
}
return json([
// 'HTTP_OK' => [200100, '請(qǐng)求成功'],
'code' => config('myconfig.statusCode.HTTP_OK')[0],
'msg' => config('myconfig.statusCode.HTTP_OK')[1],
'data' => $res,
]);
}
// session 的配置文件:
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://wtbis.cn/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
use Webman\Session\FileSessionHandler;
use Webman\Session\RedisSessionHandler;
use Webman\Session\RedisClusterSessionHandler;
return [
'type' => 'file', // or redis or redis_cluster
'handler' => FileSessionHandler::class,
'config' => [
'file' => [
'save_path' => runtime_path() . '/sessions',
],
'redis' => [
'host' => '127.0.0.1',
'port' => 6379,
'auth' => 'Abc123',
'timeout' => 2,
'database' => '',
'prefix' => 'phc_',
],
'redis_cluster' => [
'host' => ['127.0.0.1:7000', '127.0.0.1:7001', '127.0.0.1:7001'],
'timeout' => 2,
'auth' => '',
'prefix' => 'phc_',
]
],
'session_name' => 'PHPSID',
'auto_update_timestamp' => false,
'lifetime' => 7*24*60*60,
'cookie_lifetime' => 365*24*60*60,
'cookie_path' => '/',
'domain' => '',
'http_only' => true,
'secure' => false,
'same_site' => '',
'gc_probability' => [1, 1000],
];
雖然是給小程序?qū)懙慕涌冢墙涌趦?nèi)部拿到數(shù)據(jù),然后存到 session 里,在另一個(gè)方法不能調(diào)用?這說(shuō)不通啊
老大也說(shuō):session是依賴(lài)cookie實(shí)現(xiàn)的,瀏覽器每次請(qǐng)求會(huì)帶上cookie,服務(wù)端就從cookie中得到session id,然后從磁盤(pán)或者redis找對(duì)應(yīng)session id的文件或數(shù)據(jù),才能還原上次記錄的session。
瀏覽器是支持cookie和session的,當(dāng)服務(wù)器的響應(yīng)頭內(nèi)包含Set-Cookie頭時(shí),瀏覽器會(huì)把里面的鍵值對(duì)保存起來(lái),下次請(qǐng)求自動(dòng)攜帶。
換句話說(shuō),小程序的wx.request只是發(fā)起請(qǐng)求,返回結(jié)果;需要你們的前端開(kāi)發(fā)人員,解析出header頭內(nèi)容存儲(chǔ)起來(lái),下次請(qǐng)求時(shí)也攜帶。
【下面樓層,我做了一個(gè)中間件,可以用請(qǐng)求頭內(nèi)token值,作為session_id兼容webman的Session】
<?php
namespace app\middleware;
use support\Request;
use Webman\Http\Response;
use Webman\MiddlewareInterface;
/**
* Token轉(zhuǎn)換Session
* - 從請(qǐng)求頭獲取token值,設(shè)置session_id
*/
class Session implements MiddlewareInterface
{
/**
* @param Request|\Webman\Http\Request $request
* @param callable $handler
* @return Response
*/
public function process(Request|\Webman\Http\Request $request, callable $handler): Response
{
$token = $request->header('token');
if ($token && ctype_alnum($token) && strlen($token) <= 70) {
$request->setSid($token);
}
return $handler($request);
}
}
此中間件放到全局中間件內(nèi),兼容webman的session中間件。
原理是,用客戶(hù)端請(qǐng)求頭內(nèi)的token,作為sid。
感謝大神,但是我還是沒(méi)轉(zhuǎn)過(guò)這彎,那如果我的代碼跟前端沒(méi)半毛錢(qián)關(guān)系,我如何使用 session , 我突然感覺(jué)我不會(huì)用session 了.....
session是依賴(lài)cookie實(shí)現(xiàn)的,瀏覽器每次請(qǐng)求會(huì)帶上cookie,服務(wù)端就從cookie中得到session id,然后從磁盤(pán)或者redis找對(duì)應(yīng)session id的文件或數(shù)據(jù),才能還原上次記錄的session