【Java】单点登录

别来无恙 提交于 2019-12-07 18:50:24

【单点登录】

       单点登录SSO(Single Sign On)。SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。它包括可以将这次主要的登录映射到其他应用中用于同一个用户的登录的机制。

       画了一张图,大概描述下单点登录的过程。



【SSM+Dubbo+Zookeeper下实现】


Dao层
       只涉及到tb_User单张表的查询操作,Dao层使用Mybatis的逆向工程代码

Interface层
import cn.e3mall.common.utils.E3Result;


public interface LoginService {
	
	E3Result userLogin(String username,String password);
}

Service层

       用户登录信息,每一条用户信息的sessionId存入cookie中,通过cookie获取sessionId,使用UUID作为sessionId。token本质上就是sessionId。

       设置session过期时间,session过期时间在 resource.properties里配置。
#session 的过期时间
SESSION_EXPIRE=1800
       在需要用到session过期时间的方法前添加注解。   
@Value ("${SESSION_EXPIRE}")
private Integer SESSION_EXPIRE;

       代码中设置session过期时间用到了redis。   

jedisClient.expire("SESSION:" + token, SESSION_EXPIRE);

Code:
import java.util.List;
import java.util.UUID;


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 cn.e3mall.common.jedis.JedisClient;
import cn.e3mall.common.utils.E3Result;
import cn.e3mall.common.utils.JsonUtils;
import cn.e3mall.mapper.TbUserMapper;
import cn.e3mall.pojo.TbUser;
import cn.e3mall.pojo.TbUserExample;
import cn.e3mall.pojo.TbUserExample.Criteria;
import cn.e3mall.sso.service.LoginService;


/**
 * 
 * @author 璐
 *
 */


@Service
public class LoginServiceImpl implements LoginService {


	@Autowired 
	private TbUserMapper userMapper;
	@Autowired
	private JedisClient jedisClient;
	@Value ("${SESSION_EXPIRE}")
	private Integer SESSION_EXPIRE;
	
	
	@Override
	public E3Result userLogin(String username, String password) {


		//1.根据用户名查询用户信息
		TbUserExample example = new TbUserExample();
		Criteria criteria = example.createCriteria();
		criteria.andUsernameEqualTo(username);
		//查询用户登录信息是否存在
		List<TbUser> list  = userMapper.selectByExample(example);
		
		//如果用户登录的账号密码不存在,则提示错误
		if(list == null || list.size()==0){
			return E3Result.build(400, "用户名或密码错误");
		}
		//2.取用户信息
		TbUser user = list.get(0);
		//判断密码是否正确
		if(!DigestUtils.md5DigestAsHex(password.getBytes()).equals(user.getPassword())){
			return E3Result.build(400, "用户名或密码错误");
		}
		
		//3.正确生成token
		String token = UUID.randomUUID().toString();
		
		//4.用户信息写入redis,key:token ,value:用户信息
		user.setPassword(null);
		jedisClient.set("SESSION:" + token, JsonUtils.objectToJson(user));
		
		//5.设置session过期时间
		jedisClient.expire("SESSION:" + token, SESSION_EXPIRE);
		//6.返回token
		return E3Result.ok(token);
	}


}
       Service写好之后,在applicationContext-service.xml 里暴露服务接口。

Controller层

       系统拆分成了很多不同的工程,实现登录要做到跨域名访问,Cookie是域名隔离的,可以跨域名访问。所以我们在common里引入了一个cookie的工具类。


1.cookie中保存token的key存放在resource.properties里
#cookie中保存token的key
TOKEN_KEY=token

2.Controller 里的在引用 value的标签
@Value("${TOKEN_KEY}")
	private String TOKEN_KEY;

3.将token写入cookie。

CookieUtils.setCookie(request, response, TOKEN_KEY, token);

 Code:

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


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;


import cn.e3mall.common.utils.CookieUtils;
import cn.e3mall.common.utils.E3Result;
import cn.e3mall.sso.service.LoginService;


@Controller
public class LoginController {


	@Autowired 
	private LoginService  loginService;
	
	@Value("${TOKEN_KEY}")
	private String TOKEN_KEY;
	
	@RequestMapping("/page/login")
	public String showLogin(){
		return "login";
	}
	
	@RequestMapping(value="/user/login",method=RequestMethod.POST)
	@ResponseBody
	public E3Result login(String username,String password,
			HttpServletRequest request,HttpServletResponse response){
		
		//调用service的用户登录方法
		E3Result e3Result = loginService.userLogin(username, password);
		//判断是否登录成功
		if(e3Result.getStatus() == 200){
			String token=e3Result.getData().toString();
			//登录成功需要把token写入cookie
			CookieUtils.setCookie(request, response, TOKEN_KEY, token);
			
		}
		return e3Result;
	}
}
       Controller方法写好之后,要在springmvc.xml 文件里引用Dubbo服务。

【小结】

        单点登录的大致实现过程做了一个小结,还有待深入学习。以上如有错误请各位看官评论指出~

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!