e3mall项目:单点登录系统
准备工作:创建SSO服务层(e3-sso),并在其目录创建子工程(e3-sso-interface、e3-sso-service)。创建SSO表现层(e3-sso-web),并导入静态资源。
目录结构如下:
一、服务层相关(e3-sso)
(1)配置文件参考之前的服务层项目,注意在配置dubbo服务注册即可
(2)代码(e3-sso-interface、e3-sso-service)
package cn.e3mall.sso.service;
import cn.e3mall.common.entity.E3Result;
import cn.e3mall.entity.TbUser;
/**
* 用户相关 service层
* @Auther: xushuai
* @Date: 2018/5/29 10:13
* @Description:
*/
public interface UserService {
/**
* 校验信息是否可以注册
* @auther: xushuai
* @date: 2018/5/29 10:14
*/
E3Result check(String param, Integer type);
/**
* 用户注册
* @auther: xushuai
* @date: 2018/5/29 10:42
*/
E3Result register(TbUser user);
/**
* 用户登录
* @auther: xushuai
* @date: 2018/5/29 14:57
*/
E3Result login(String username,String password);
/**
* 获取登录的用户
* @auther: xushuai
* @date: 2018/5/29 16:30
*/
E3Result getLoginUser(String token);
}
package cn.e3mall.sso.service.impl;
import cn.e3mall.common.entity.E3Result;
import cn.e3mall.common.redis.JedisClient;
import cn.e3mall.common.utils.JsonUtils;
import cn.e3mall.dao.TbUserMapper;
import cn.e3mall.entity.TbUser;
import cn.e3mall.entity.TbUserExample;
import cn.e3mall.sso.service.UserService;
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 java.util.Date;
import java.util.List;
import java.util.UUID;
/**
* 用户相关 service层实现
* @Author: xushuai
* @Date: 2018/5/29
* @Time: 10:15
* @Description:
*/
@Service
public class UserServiceImpl implements UserService {
@Autowired
private TbUserMapper userMapper;
@Autowired
private JedisClient jedisClient;
@Value("${session.timeout}")
private Integer timeout;
@Override
public E3Result check(String param, Integer type) {
TbUserExample example = new TbUserExample();
//校验type是否合法
if(type == 1){
example.createCriteria().andUsernameEqualTo(param);
} else if (type == 2){
example.createCriteria().andPhoneEqualTo(param);
} else if (type == 3){
example.createCriteria().andEmailEqualTo(param);
} else {
return E3Result.build(500,"不合法的数据校验类型");
}
//根据type查询数据库
List<TbUser> tbUsers = userMapper.selectByExample(example);
//判断结果集中是否有数据
if(tbUsers != null && tbUsers.size() > 0){
return E3Result.ok(false);
}
return E3Result.ok(true);
}
@Override
public E3Result register(TbUser user) {
//数据有效性校验
if(StringUtils.isNotBlank(user.getUsername()) &&
StringUtils.isNotBlank(user.getPassword()) &&
StringUtils.isNotBlank(user.getPhone())){
//校验用户名是否已存在
if(!(Boolean) (check(user.getUsername(),1).getData())){
return E3Result.build(500,"该用户名已被注册");
}
//校验用户名是否已存在
if(!(Boolean) (check(user.getPhone(),2).getData())){
return E3Result.build(500,"该手机号已被注册");
}
//校验通过,补全数据
user.setCreated(new Date());
user.setUpdated(new Date());
//使用MD5对密码进行加密
String password = user.getPassword();
password = DigestUtils.md5DigestAsHex(password.getBytes());
user.setPassword(password);
//注册用户
userMapper.insertSelective(user);
return E3Result.ok();
}
return E3Result.build(500,"数据不完整");
}
@Override
public E3Result login(String username,String password) {
//对password进行MD5加密
String md5PWD = DigestUtils.md5DigestAsHex(password.getBytes());
//校验账号密码是否正确
TbUserExample example = new TbUserExample();
example.createCriteria().andUsernameEqualTo(username).andPasswordEqualTo(md5PWD);
//使用账号密码,进行查询
List<TbUser> users = userMapper.selectByExample(example);
if(users == null || users.size() == 0){
return E3Result.build(500,"用户名或密码错误");
}
//将用户信息保存到token
String token = UUID.randomUUID().toString();
//生成缓存的key值
String key = "SESSION:" + token;
//将用户信息保存到redis缓存中
jedisClient.set(key, JsonUtils.objectToJson(users.get(0)));
//设置过期时间
jedisClient.expire(key,timeout);
//返回登录成功
return E3Result.ok(token);
}
@Override
public E3Result getLoginUser(String token) {
//生成redis的key值
String key = "SESSION:" + token;
//查询用户登录状态
String s = jedisClient.get(key);
//查看是否查询到结果
if(StringUtils.isBlank(s)){
return E3Result.build(201,"该用户登录已过期");
}
//将查询到的结果转换为User对象
TbUser user = JsonUtils.jsonToPojo(s,TbUser.class);
//刷新登录过期时间
jedisClient.expire(key,timeout);
//返回结果
return E3Result.ok(user);
}
}
二、表现层相关(e3-sso-web)
(1)配置文件参考之前的表现层项目
(2)工具类导入(CookieUtils)
(3)相关代码(PageController、UserController)
package cn.e3mall.sso.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* 页面跳转Controller
* Author: xushuai
* Date: 2018/5/28
* Time: 21:52
* Description:
*/
@Controller
public class PageController {
/**
* 跳转到注册页面
* @auther: xushuai
* @date: 2018/5/28 21:54
*/
@RequestMapping("/page/register")
public String register(){
return "register";
}
/**
* 跳转到登录页面
* @auther: xushuai
* @date: 2018/5/28 21:54
*/
@RequestMapping("/page/login")
public String login(){
return "login";
}
}
package cn.e3mall.sso.controller;
import cn.e3mall.common.entity.E3Result;
import cn.e3mall.common.utils.CookieUtils;
import cn.e3mall.common.utils.JsonUtils;
import cn.e3mall.entity.TbUser;
import cn.e3mall.sso.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 用户相关 Controller
* Author: xushuai
* Date: 2018/5/28
* Time: 22:30
* Description:
*/
@Controller
public class UserController {
@Autowired
private UserService userService;
@Value("${cookie.key}")
private String cookieName;
/**
* 注册校验
* @auther: xushuai
* @date: 2018/5/29 10:07
*/
@RequestMapping("/user/check/{param}/{type}")
@ResponseBody
public E3Result checkRegister(@PathVariable String param,@PathVariable Integer type){
return userService.check(param,type);
}
/**
* 注册用户
* @auther: xushuai
* @date: 2018/5/29 16:28
*/
@RequestMapping(value = "/user/register",method = RequestMethod.POST)
@ResponseBody
public E3Result register(TbUser user,String password2){
//再次校验密码是否一致
if(password2.equals(password2)){
//两次密码一致,允许注册
return userService.register(user);
}
return E3Result.build(500,"两次输入密码不一致");
}
/**
* 登录
* @auther: xushuai
* @date: 2018/5/29 16:29
*/
@RequestMapping(value = "/user/login",method = RequestMethod.POST)
@ResponseBody
public E3Result login(String username, String password,
HttpServletRequest request, HttpServletResponse response){
E3Result result = userService.login(username, password);
//判断是否登录成功
if(result.getStatus() == 200){
//登录成功,将token写入cookie
String token = result.getData().toString();
CookieUtils.setCookie(request,response,cookieName,token);
}
return result;
}
/**
* 获取当前登录的用户信息
* @auther: xushuai
* @date: 2018/5/29 16:28
*/
@RequestMapping(value = "/user/token/{token}",produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public String getLoginUser(@PathVariable String token,String callback){
E3Result result = userService.getLoginUser(token);
String json = JsonUtils.objectToJson(result);
//判断是否为跨域请求
if(StringUtils.isNotBlank(callback)){
//是跨域请求,进行处理
return callback + "(" + json + ");";
}
//不是跨域请求,直接返回
return json;
}
}