以前处理过一个BUG,在其他端口点击跳转到网页端时,用户继续操作时没有权限上传失败、或没有浏览权限跳转到404页面
这个问题的是因为在跳转的过程中token没有传递过来,为了解决这个问题,写了一个跳转页面,接收加密过的用户id、sessionkey、url
在此页面进行权限验证并存入缓存,成功则跳转到url,废话不多说,上代码:
//服务端
<?php
//加密解密服务
require("common/aes.php");
// 定义项目路径
defined('API_ROOT') || define('API_ROOT', dirname(__FILE__) . '/..');
define('VERSION', 'test'); // develop=>开发,test=>测试,product=>正式
// 引入composer
require_once API_ROOT . '/vendor/autoload.php';
// 时区设置
date_default_timezone_set('Asia/Shanghai');
session_start();
$userid = $_GET['u'];
$sessionKey = $_GET['s'];
$go = $_GET['g'];
if (isset($userid) && strlen($userid) > 0 && isset($sessionKey) && strlen($sessionKey) > 0 && isset($go) && strlen($go) > 0) {
$des = new TripleAES();
$userid = (int)trim($des->Decrypt($userid));
$sessionKey = trim($des->Decrypt($sessionKey));
$go = trim($des->Decrypt($go));
$checkErrMsg = "";
$data = DoUserLogin($userid, "", $sessionKey, $checkErrMsg) or die('你当前已离线,请重新登录在刷新重试!' . $userid . '--' . $sessionKey . '---' . $go);
$nulstr = strstr($go, chr(0));
if ($nulstr) {
$go = substr($go, 0, strlen($go) - strlen($nulstr));
}
header("Location: " . $go);
} else {
die('你当前已离线,请重新登录在刷新重试!');
}
//验证并缓存用户数据
function DouserLogin($userid, $password, $sessionKey, &$checkErrMsg)
{
try {
$client = \GrpcServer\ClientFactory::createClient(
'tokencheck.TokenCheck', VERSION
);
$req = new \Cfwf\Micro_service\Tokencheck\CheckUserTokenWhenClientAccessRequest();
$req->setUserid($userid);
$req->setToken($sessionKey);
$req->setOs(1);
list($data) = $client->CheckUserTokenWhenClientAccess($req)->wait();
$lists = $data->toArray();
if ($lists['result'] != 1) {
return false;
} else {
$request['os'] = 1;
$request['user_id'] = $userid;
$request['token'] = $sessionKey;
$request['web_level'] = 0;
$AccountGrpc = new \Common\Domain\AccountGrpc();
$data = $AccountGrpc->setLoginUserInfo($request, VERSION);
$_SESSION['loginUserInfo'] = $data;
return $data;
}
} catch (\Exception $e) {
return false;
}
}
?>
跳转到新页面的时候,发现有时还是没有权限,经过检查,前端把token存在在浏览器缓存了,刚跨平台跳转当然不会有浏览器缓存,所以在前端请求前需要把token存入浏览器缓存内。
我在vue的钩子方法内,首先调用请求到接口获取用户数据,保证后续的请求都拿到了 token,还是直接上代码。
...
created() {
this.id = this.$route.query.id; // 栏目id
this.a_id = this.$route.query.a_id; // 活动id
this.getLoginInfo();
},
.....
methods: {
// 获取登录数据
//这个接口在白名单内,无需token验证
async getLoginInfo() {
const data = {
s: "Common.Account.getLoginUserInfo",
};
//调用接口
let response = await api.post(url.httpUrl, data);
const res = response.data.data;
const isLogin = api.eventListener(res);
this.user_id = localStorage.getItem("ms_userid");
this.uploadUrl = url.uploadPath; // 文件上传地址
this.uploadData = {
UserId: localStorage.getItem("ms_userid"),
SessionKey: localStorage.getItem("ms_token"),
OS: 4,
CheckCode: api.randomString(40),
};
this.options = {
target: url.uploadPath, // 上传地址
testChunks: false,
singleFile: false, // 启用单个文件上传。上传一个文件后,第二个文件将超过现有文件,第一个文件将被取消。
chunkSize: "1048576" * 1, //分块大小 单位(M)
query: {
//传参
UserId: localStorage.getItem("ms_userid"),
SessionKey: localStorage.getItem("ms_token"),
OS: 4,
PluginType: 1,
},
};
this.function1();
},
},
...
//api.js内方法
// 监听登录状态做出相应处理,返回是否登录
eventListener(res) {
if (res) {
localStorage.setItem("ms_username", res.username);
localStorage.setItem("ms_userid", res.userid);
localStorage.setItem("ms_userface", res.userface);
localStorage.setItem("ms_schoolid", res.schoolid);
localStorage.setItem("ms_identity", JSON.stringify(res.identity));
localStorage.setItem("ms_userAuth", JSON.stringify(res.userAuth));
localStorage.setItem("ms_schoolname", res.schoolname);
localStorage.setItem("ms_token", res.token);
localStorage.setItem("ms_token_endtime", res.token_endtime);
return true;
} else {
//清除缓存
this.clearLoginInfo();
return false;
}
},
//api.js 内封装的post请求
post(url, data) {
if (!data.userid) {
data.userid = localStorage.getItem("ms_userid") ? localStorage.getItem("ms_userid") : 1;
}
//前端请求携带的token
data.token = localStorage.getItem("ms_token");
return axios({
method: 'post',
url,
data: qs.stringify(data),
timeout: 30000,
headers: {}
}).then(function (response) {
if (response.data.ret != 200) {
v.$notify({
message: "当前页面部分功能暂时不可用,请稍后再试。",
offset: 100
});
return false;
}
return response;
}
).catch(function (error) {
console.log(error);
// 网络异常引发的错误
});
},
至此,这个因为权限已经解决了。