服务端模拟浏览器cookie_如何在移动端与服务端互通会话信息

作者:全天计划玩家交流群

编辑:字节逆旅

原文:https://www.jianshu.com/p/5cdf6c5278a1

众所周知,做过Web开发的小伙伴可能知道,在浏览器向服务器发一个请求,服务器端会为当前的访问者创建一个session会话,随着浏览器的关闭而会话结束。现在问题来了,移动客户端咋整呢(IOS/Android啥的)?

5edf363b12199feb7a4abc4e3d32694d.png

鄙人研究了一番,发现IOS/Android用原生接口发请求最大滴特点是每一次建一个会话,这样登录功能也就基本废了。登录功能的意义是将用户身份验证成功的信息存储在session里,结果每一次请求一个新的session这可不OK啊!

那么在登录时,如何保证客户端创建的session在后续的接口请求中都能够行之有效的为客户端提供会话的操作,比如用户信息实体的存放,用户权限功能菜单的存放啥的。

首先来科普一个概念:Cookies,下面会有解释;还有一个比较流行的移动端开发概念access_token(访问令牌),做过微信开发的应该都懂,这个是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token,开发者需要进行妥善保存。

Cookies

浏览器的工作原理也是基于cookies,这也就能解释每一次为何清空cookie后网站需要重新登录。浏览器访问服务端时,服务端在响应信息里包含了cookie信息,这个cookie里就有sessionId,这个sessionId会被浏览器自己缓存在本地cookie里,后续访问该网站的一切请求时都会自动在HTTP请求头Header里带着cookie信息。因此,服务器通过cookie里的sessionId来判断当前访问者的身份,并且从会话集合里匹配当前sessionId所对应的会话对象。

access_token

再说说另外一个概念access_token访问令牌,这个是自己约定的,根据开发需要。比如有这样的一个场景:用户登录请求,用户登录时,会带着用户名name和密码pwd来访问登录接口。如果服务端确认该用户是合法的,那么咱们应该由服务端生成一个access_token,保存在服务端的session会话里,并且将这个access_token返回给客户端。

OK,到这里,客户端总共获取到了两个东西,包含有sessionId的cookie和access_token,有了这两个东西,客户端后续在请求服务端的任何一个接口时,需带着access_token和Cookie即可。服务端会通过cookie识别你属于哪个session,通过access_token判断你是否合法,此次登录是否过期(服务端说了算)。上代码:

后端

//
//一.登录时创建会话且返回access_token到客户端
/

//access_token令牌作为登录状态标识
HttpServletRequest req = Mvcs.getReq();
HttpSession session = req.getSession(true);//创建会话
//uuid作为token
String access_token = UUID.randomUUID().toString();
session.setAttribute("access_token", access_token);
//out.print("access_token:"+access_token);



//二.后续的接口访问中服务端过滤链逻辑

HttpServletRequest request = Mvcs.getReq();
HttpSession httpSession = request.getSession(true);
String rat= request.getParameter("access_token");
String sat= (String)httpSession.getAttribute("access_token");
if(rat!= null && rat.equals(sat)) {
//如果相等,说明access_token是有效的.
    //放行。。。
}

app

前面提到过,如果在浏览器端请求接口,session值会自动传到后台,部署在浏览器的前端项目可以不用保存;但是在app上,每次请求都会重建一个会话,为了保证登录后的后续服务请求能正常进行,就需要对登录的session信息进行保存。这是一段在uniapp中的代码,storage_CURRENT_USER 这个键值存的就是session信息。

// 登录
 login({commit},userInfo) {
  return new Promise((resolve, reject) => {
   login(userInfo).then(data => {
    //data为一个数组,数组第一项为错误信息,第二项为返回数据
    var [error, res]  = data;
    //成功就进行缓存
    //将用户id设置为 模拟token令牌
    commit("SET_TOKEN", res.data.data.id);
    try {
        uni.setStorageSync('storage_token', res.data.data.id);
    } catch (e) {
        // error
    }
    try {
        uni.setStorageSync('storage_CURRENT_USER', res.cookies[0]);
    } catch (e) {
        // error
    }
    resolve(res);
    reject(error);
   });
  })
 }

接下来,只要你在HTTP请求头里提交了形如:Cookie:JSESSIONID=16E11471753944CF4F68A9F665E9B97F 键值对,服务器会自动根据cookie里包含的sessionId去在服务端匹配属于这个id的session并提供服务。下面是一个请求示例,注意键值Cookie要区分大小写。“getCookie”方法可以理解为app端封装的保存session信息的方法。

request({
   url: "http:********",
   method: "post",
   header:{"Cookie": getCookie('storage_CURRENT_USER')},
   data
 });
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值