平常在做web开发,shiro的会话管理器采用的是DefaultWebSessionManager,它会在浏览器写下一个JSESSIONID的cookie。DefaultWebSessionManager默认采用的seesiondao是new ServletContainerSessionManager(),当然我们可以自己重写sessiondao将session保存到redis或数据库。
浏览器会携带这个JESESSIONID访问项目,shiro根据JESESSIONID分析出一个sessionid(其实两者是相等的),根据这个sessionid调用sessionDao中的方法,找到session。
但最近做微信小程序,发现小程序无法像web浏览器一样,在上面写cookie。那只能采取,每次请求都带上JSESSIONID,然后重写shiro分析请求cookie的方法,让它不分析cookie而分析请求中指定的参数,当做sessionId。
小程序
先看小程序的代码,在请求头中设置了一个名为token参数(叫其他名字也可以)
var header;
header = {
'content-type': 'application/x-www-form-urlencoded;charset=utf-8',
'token': 'e1cacec2-044a-4d16-8d7b-dfa6e9accc83a'
};
wx.request({
// url: 'http://localhost:8090/focus/resource/getCurrentUserResourceTree',
url: 'http://localhost:8090/hhh',
//发送给后台的数据
data: {},
//get为默认方法/POST
method: 'get',
header: header,
success: function (res) {
// that.setData({
// //如果在sucess直接写this就变成了wx.request()的this了.必须为getdata函数的this,不然无法重置调用函数
// videos: res.data
// })
//res.data相当于ajax里面的data,为后台返回的数据
console.log(res.data)
}
})
自定义session管理器,重写getSessionId方法
继承DefaultWebSessionManager,重写getSessionId方法,逻辑是如果请求头中有token,就分析token,没有就调用父类的方法,依然按原先分析cookie中的参数
public class StatelessSessionManager extends DefaultWebSessionManager {
/**
* 这个是服务端要返回给客户端,
*/
public final static String TOKEN_NAME = "TOKEN";
/**
* 这个是客户端请求给服务端带的header
*/
public final static String HEADER_TOKEN_NAME = "token";
public final static Logger LOG = LoggerFactory.getLogger(StatelessSessionManager.class);
private static final String REFERENCED_SESSION_ID_SOURCE = "Stateless request";
/**
* 重写getSessionId,分析请求头中的指定参数,做用户凭证sessionId
*/
@Override
protected Serializable getSessionId(ServletRequest request, ServletResponse response){
String id = WebUtils.toHttp(request).getHeader(HEADER_TOKEN_NAME);
//System.out.println("id:"+id);
if(StringUtils.isEmpty(id)){
//如果没有携带id参数则按照父类的方式在cookie进行获取
// System.out.println("super:"+super.getSessionId(request, response));
return super.getSessionId(request, response);
}else{
//如果请求头中有 authToken 则其值为sessionId
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,REFERENCED_SESSION_ID_SOURCE);
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID,id);
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID,Boolean.TRUE);
return id;
}
}
}