shiro实现APP保持登录状态,以及web统一登录认证和权限管理,会话保持在web和APP之间。

本文介绍了如何使用Shiro在Java项目中实现APP和Web的统一登录认证及权限管理。针对APP需要长时间保持登录状态的需求,提出通过存储cookie并结合数据库策略来处理过期session的问题。当服务器session过期,APP自动发起登录请求以获取新session,同时讨论了安全性、session存储、更新频率和IP验证等策略。
摘要由CSDN通过智能技术生成

先说下背景,项目包含一个管理系统(web)和门户网站(web),还有一个手机APP(包括Android和IOS),三个系统共用一个后端,在后端使用shiro进行登录认证和权限控制。好的,那么问题来了

先说web端

1.因为一般网页主需要记住7天密码(或者稍微更长)的功能就可以了,可以使用cookie实现,而且shiro也提供了记住密码的功能,在服务器端session不需要保存过长时间。

再说app端

2.因为APP免密码登录时间需要较长(在用户不主动退出的时候,应该一直保持登录状态),这样子在服务器端就得把session保存很长时间,给服务器内存和性能上造成较大的挑战,存在的矛盾是:APP需要较长时间的免密码登录,而服务器不能保存过长时间的session。

 解决办法:

  • APP第一次登录,使用用户名和密码,如果登录成功,将cookie保存在APP本地(比如sharepreference),后台将cookie值保存到user表里面
  • APP访问服务器,APP将cookie添加在heade里面,服务器session依然存在,可以正常访问
  • APP访问服务器,APP将cookie添加在heade里面,服务器session过期,访问失败,由APP自动带着保存在本地的cookie去服务器登录,服务器可以根据cookie和用户名进行登录,这样服务器又有session,会生成新的cookie返回给APP,APP更新本地cookie,又可以正常访问
  • 用户手动退出APP,删除APP本次存储的cookie,下次登录使用用户名和密码登录

这种方法存在的问题:

  1. cookie保存在APP本地,安全性较低,可以通过加密cookie增加安全性
  2. 每次服务器session失效之后,得由APP再次发起登录请求(虽然用户是不知道的),但是这样本身就会增加访问次数,好在请求数量并不是很大,不过这种方式会使cookie经常更新,反而增加了安全性。

这里给出另外一种实现方式:
实现自己的SessionDao,将session保存在数据库,这样子的好处是,session不会大量堆积在内存中,就不需要考虑session的过期时间了,对于APP这种需要长期保存session的情况来说,就可以无限期的保存session了,也就不用APP在每次session过期之后重新发送登录请求了。实现方式如下:

1. 数据库设计 (需要的话自己扩展)

                       

2. 实体类
import java.io.Serializable;
import java.util.Date;



/**
 * 用户session
 * 
 * @author flyingTiger
 * @email gaofeihu95@163.com
 * @date 2018-03-05 15:44:08
 */
public class SysUserSessionEntity implements Serializable {
	private static final long serialVersionUID = 1L;
	
	//id
	private String id;
	//session
	private String session;
	//cookie
	private String cookie;
	//user_id
	private Long userId;
	//创建时间
	private Date createTime;
	//最后更新时间
	private Date lastUpTime;
	//状态
	private String status;

	/**
	 * 设置:id
	 */
	public void setId(String id) {
		this.id = id;
	}
	/**
	 * 获取:id
	 */
	public String getId() {
		return id;
	}
	/**
	 * 设置:session
	 */
	public void setSession(String session) {
		this.session = session;
	}
	/**
	 * 获取:session
	 */
	public String getSession() {
		return session;
	}
	/**
	 * 设置:cookie
	 */
	public void setCookie(String cookie) {
		this.cookie = cookie;
	}
	/**
	 * 获取:cookie
	 */
	public String getCookie() {
		return cookie;
	}
	/**
	 * 设置:user_id
	 */
	public void setUserId(Long userId) {
		this.userId = userId;
	}
	/**
	 * 获取:user_id
	 */
	public Long getUserId() {
		return userId;
	}
	/**
	 * 设置:创建时间
	 */
	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}
	/**
	 * 获取:创建时间
	 */
	public Date getCreateTime() {
		return createTime;
	}
	/**
	 * 设置:最后更新时间
	 */
	public void setLastUpTime(Date lastUpTime) {
		this.lastUpTime = lastUpTime;
	}
	/**
	 * 获取:最后更新时间
	 */
	public Date getLastUpTime() {
		return lastUpTime;
	}
	/**
	 * 设置:状态
	 */
	public void setStatus(String status) {
		this.status = status;
	}
	/**
	 * 获取:状态
	 */
	public String getStatus() {
		return status;
	}
}

3. 在此之前我已经实现过sessionDao ,是将session放到redis里面

import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.concurrent.TimeUnit;

/**
 * shiro session dao
 *
 * @author flyingTiger
 * @email gaofeihu95@163.com
 * @date  2017/9/27 21:35
 */
&
  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值