在分布式架构中如何共享session?

可以使用redis模拟session(redis也可以设置有效时间),实现共享session的功能。

首先写个Service,在里面完成下面的业务:

    用户输入登录信息提交登录,然后在service中和数据库中的数据进行查询比对,如果符合则将该用户的用户信息保存到redis中,将对应的key值保存到cookie中,为了确保cookie的唯一性,可以使用uuid。这样在cookie的有效时间内,用户在使用需要登录权限的功能时,就可以根据这个cookie去redis中取得用户信息,从而通过用户登陆状态校验。

至于Controller怎么写,根据具体的情况而定。大致的流程是这样。

package com.taotao.sso.service.impl;

import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import com.fasterxml.jackson.core.util.TextBuffer;
import com.taotao.common.utils.CookieUtils;
import com.taotao.common.utils.JsonUtils;
import com.taotao.common.utils.TaotaoResult;
import com.taotao.mapper.TbUserMapper;
import com.taotao.pojo.TbUser;
import com.taotao.pojo.TbUserExample;
import com.taotao.pojo.TbUserExample.Criteria;
import com.taotao.sso.component.JedisClient;
import com.taotao.sso.service.LoginService;

@Service
public class LoginServiceImpl implements LoginService {

	@Autowired
	private TbUserMapper tbUserMapper;

	@Autowired
	private JedisClient jedisClient;

	@Value("${REDIS_SESSION_KEY}")
	private String REDIS_SESSION_KEY;

	@Value("${SESSION_EXPIRE}")
	private Integer SESSION_EXPIRE;// 过期时间

	@Override
	public TaotaoResult login(String username, String password,
			HttpServletRequest request, HttpServletResponse response) {
		// 校验用户名和密码
		TbUserExample example = new TbUserExample();
		Criteria cia = example.createCriteria();
		cia.andUsernameEqualTo(username);
		List<TbUser> list = tbUserMapper.selectByExample(example);
		if (list == null || list.isEmpty()) {
			return TaotaoResult.build(400, "用户名或密码错误");
		}
		TbUser user = list.get(0);
		String userpassword = user.getPassword();// 这里从数据库中取出的密文。
		// 将用户提交的密码加密后和密文比较,如果不想等即密码错误。
		if (!userpassword
				.equals(DigestUtils.md5DigestAsHex(password.getBytes()))) {
			return TaotaoResult.build(400, "用户名或密码错误");
		}

		// 登录成功,生成token(使用uuid生成唯一的字符串作为token)
		String token = UUID.randomUUID().toString();//这就相当于是:SESSIONID
		// 将用户信息写入redis,token为key的一部分
		// key格式:REDIS_SESSION:{TOKEN} value格式:user转换成json格式即可
		// user保存之前要序列化,序列化之前要将密码清空
		user.setPassword(null);
		jedisClient.set(REDIS_SESSION_KEY + ":" + token,
				JsonUtils.objectToJson(user));
		jedisClient.expire(REDIS_SESSION_KEY + ":" + token, SESSION_EXPIRE);// 设置reids中该用户信息的过期时间
		// 写cookie
		CookieUtils.setCookie(request, response, "Token", token);// 这里没有设置浏览器Cookie过期时间,那么默认的过期时间就是关闭浏览器就会过期。

		return TaotaoResult.ok(token);
	}

	/**
	 * 查session(redis缓存)
	 */
	@Override
	public TaotaoResult getUserByToken(String token) {
		// 根据token取用户信息
		String json = jedisClient.get(REDIS_SESSION_KEY + ":" + token);
		// 判断是否查询到结果
		if (StringUtils.isBlank(json)) {
			return TaotaoResult.build(400, "用户session已经过期");
		}
		// 把json转换成java对象
		TbUser user = JsonUtils.jsonToPojo(json, TbUser.class);
		// 更新session的过期时间
		jedisClient.expire(REDIS_SESSION_KEY + ":" + token, SESSION_EXPIRE);

		return TaotaoResult.ok(user);

	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值