单点登录SSO(Single Sign On)。SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。它包括可以将这次主要的登录映射到其他应用中用于同一个用户的登录的机制。
画了一张图,大概描述下单点登录的过程。
import cn.e3mall.common.utils.E3Result;
public interface LoginService {
E3Result userLogin(String username,String password);
}
#session 的过期时间
SESSION_EXPIRE=1800
在需要用到session过期时间的方法前添加注解。
@Value ("${SESSION_EXPIRE}")
private Integer SESSION_EXPIRE;
代码中设置session过期时间用到了redis。
jedisClient.expire("SESSION:" + token, SESSION_EXPIRE);
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 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 里暴露服务接口。
#cookie中保存token的key
TOKEN_KEY=token
@Value("${TOKEN_KEY}")
private String TOKEN_KEY;
3.将token写入cookie。
CookieUtils.setCookie(request, response, TOKEN_KEY, token);
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服务。