通过redis实现单点登录
1登录(controller)
/**
* 登录
* @param username
* @param password
* @param url
* @param request
* @param response
* @return
*/
@RequestMapping(value = "/login", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<Map<String,String>> login(@RequestParam("username") String username,
@RequestParam("password") String password,
@RequestParam("url") String url,
HttpServletRequest request,
HttpServletResponse response){
Cookie[] cookies = request.getCookies();
HashMap<String, String> map = new HashMap<>();
//进行登录
User user = loginService.login(username,password);
//生成token当做key存到redis中
String token = UUID.randomUUID().toString();
//登录失败
if (user == null){
//弹出友好提示信息
return ResponseEntity.fail(null,"账号密码错误,请重新登录!");
}
//登录成功
else {
//将token当成key,username当成value,存到redis中,token的过期时间设置为30分钟
Jedis jedis = JedisUtil.getMasterJedis();
String ret = JedisUtil.setStringInSeconds(jedis, token, username, 30 * 60);
if (StringUtils.isNotEmpty(ret)){
//将token放入Cookie
Cookie ctoken = new Cookie("token", token);
//Cookie的存放时间为一天
ctoken.setMaxAge(24*60*60);
ctoken.setPath("/");
response.addCookie(ctoken);
map.put("redirect",url);
//跳转到指定页面
return ResponseEntity.success(map);
}
//如果存入redis失败,进行熔断处理
else {
return ResponseEntity.fail(null,"服务器异常,请稍后再试!");
}
}
}
1.1在service进行登录的逻辑处理
/**
* 进行登录
* @param username
* @param password
* @return
*/
@Override
public User login(String username, String password) {
try {
//进行密码加密,之后对比数据库中的密码,校验是否匹配
password = MD5Utils.getEncryptedPwd(password);
User user = userMapper.selectByName(username);
if (user != null && user.getPassword().equals(password)){
return user;
}
//账号或者密码错误
return null;
}catch (Exception e){
e.printStackTrace();
log.error("触发熔断机制,错误详情:" + e);
return null;
}
}
2登出(controller)
/**
* 登出,注销cookie,redis中的token缓存
* @param request
* @param response
* @return
*/
@RequestMapping(value = "/outlogin",method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<Map<String,String>> outlogin(HttpServletRequest request,HttpServletResponse response){
try {
HashMap<String, String> map = new HashMap<>();
//删除cookie中的token消息头
String token = "";
Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {
if (cookie.getName().equals("token")){
token = cookie.getValue();
cookie.setMaxAge(0);
}
}
//删除redis中的token缓存
Jedis jedis = JedisUtil.getMasterJedis();
jedis.del(token);
map.put("redirect","login");
return ResponseEntity.success(map);
}catch (Exception e){
log.error("进行熔断处理,错误详情:" + e );
return ResponseEntity.fail(null,"服务器异常,请稍后再试!");
}
}
3注册账号(controller)
/**
* 注册账号
* @param confirmPwd
* @param vcode
* @param user
* @return
*/
@RequestMapping(value = "/regist")
@ResponseBody
public ModelAndView regist(@RequestParam("confirmPwd") String confirmPwd,
@RequestParam("vcode") String vcode,
User user){
ModelAndView view = new ModelAndView();
try {
view = userService.registAccount(confirmPwd, vcode, user);
return view;
}catch (Exception e){
log.error("注册失败,详细信息请看日志:" + e);
view.addObject("result",false);
view.addObject("message","服务器异常,请稍后重试!");
return view;
}
}
3.1在service层进行账号注册的逻辑处理
/**
* 账号注册
* @param confirmPwd
* @param vcode
* @param user
* @return
*/
@Override
public ModelAndView registAccount(String confirmPwd, String vcode, User user) {
ModelAndView view = new ModelAndView();
String username = user.getName();
String password = user.getPassword();
//校验用户名能否使用
if (username == null || username.trim().isEmpty()){
ResponseEntity.fail(null,"用户名不能为空");
}else if (username.length()<5 || username.length()>15){
ResponseEntity.fail(null,"用户名的长度只能在5-15之间");
}else if (this.queryByUsername(username) != null){
ResponseEntity.fail(null,"用户名已存在,请更换用户名");
}
//校验密码
if (password == null || password.trim().isEmpty()){
ResponseEntity.fail(null,"密码不能为空");
}else if (password.length()<5 || password.length()>15){
ResponseEntity.fail(null,"密码的长度只能在5-15之间");
}
//校验确认密码是否和密码一致
if (confirmPwd == null || confirmPwd.trim().isEmpty()){
ResponseEntity.fail(null,"确认密码不能为空");
}else if (!confirmPwd.equals(password)){
ResponseEntity.fail(null,"两次密码不一致");
}
//校验验证码:和redis中的验证码进行对比
Jedis jedis = JedisUtil.getMasterJedis();
String verifyCode = jedis.get("cellphone");
if (verifyCode.isEmpty()){
ResponseEntity.fail(null,"验证码已失效,请重新发送");
}else if (!vcode.equals(verifyCode)){
ResponseEntity.fail(null,"验证码有误,请重新输入");
}
//走到这里表名以上参数全部有效,可以进行账号注册
User user2 = new User();
user2.setName(username);
user2.setPassword(password);
user2.setAge(user.getAge());
user2.setBirthtime(user.getBirthtime());
user2.setGender(user.getGender());
user2.setTruename(user.getTruename());
user2.setTelephone(user.getTelephone());
user2.setWeixinid(user.getWeixinid());
boolean registResult = this.regist(user2);
//注册成功,跳转到登录页面
if (registResult){
view.addObject("result",registResult);
view.addObject("message","注册成功,即将跳转登录页面");
view.setViewName("login");
return view;
}else {
//注册失败,提示稍后重试
view.addObject("result",registResult);
view.addObject("message","注册失败,请稍后重试");
return view;
}
}
/**
* 新账号保存到数据库
* @param user
* @return
*/
@Override
public boolean regist(User user){
try {
String password = user.getPassword();
String encryptedPwd = null;
encryptedPwd = MD5Utils.getEncryptedPwd(password);
user.setPassword(encryptedPwd);
int ret = userMapper.insert(user);
return ret==1 ? true:false;
} catch (Exception e) {
e.printStackTrace();
log.error("注册账号失败,详情:" + e);
return false;
}
}
4页面跳转 (controller) (这里格式不规范,逻辑处理应该放到service进行,因为时间关系,这里就没有分层)
/**
* 验证token是否有效,有效跳转指定页面,无效跳转登录页面重新登录
* @param url
* @param request
* @param response
* map{redirect:重定向页面,}
* @return
*/
@RequestMapping(value = "/gotoPage", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<Map<String,String>> gotoPage(@RequestParam("url") String url, HttpServletRequest request, HttpServletResponse response){
//查看Cookie中是否有值
HashMap<String, String> map = new HashMap<>();
Cookie[] cookies = request.getCookies();
String token = "";
for (Cookie cookie : cookies) {
if (cookie.getName().equals("token")){
token = cookie.getValue();
}
}
if (org.apache.commons.lang.StringUtils.isBlank(token)){
map.put("redirect","login");
return ResponseEntity.fail(map,"登录已失效,请重新登录");
}
String username =userService.getStoreUserByUserName(token);
if (username == null || username == ""){
map.put("redirect","login");
return ResponseEntity.fail(map,"登录已失效,请重新登录");
}
if (StringUtils.isNotEmpty(username)){
try {
//在数据库中查询,是否存在响应的账号数据
User user = userService.queryByUsername(username);
//如果有url过来,重定向到url
if (user != null){
if (org.apache.commons.lang.StringUtils.isNotBlank(url)){
map.put("redirect",url);
return ResponseEntity.success(map);
}
}
}catch (Exception e){
e.printStackTrace();
log.error("登录出现异常,详细信息为:" + e);
}
}
map.put("redirect","login");
return ResponseEntity.fail(map,"未登录,请先登录");
}
5修改密码
5.1跳转到修改密码页面之前的登录认证(controller)
/**
* 跳转修改密码界面
* @param request
* @param response
* @return
*/
@RequestMapping("/toModifyPwd")
@ResponseBody
public ResponseEntity<String> toModifyPwd(HttpServletRequest request, HttpServletResponse response){
try {
String result = userService.toModifyPwd(request);
if (result != null) {
return ResponseEntity.fail(result);
}else {
return ResponseEntity.success("即将跳转到修改密码页面");
}
}catch (Exception e){
e.printStackTrace();
return ResponseEntity.fail(null,"服务器异常,请稍后再试!");
}
}
5.1.1在service层进行token验证
//跳转修改密码界面之前的验证
@Override
public String toModifyPwd(HttpServletRequest request) {
Jedis jedis = JedisUtil.getMasterJedis();
String token = "";
Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {
if (cookie.getName().equals("token")){
token = cookie.getValue();
}
}
if (StringUtils.isEmpty(token)){
return "未登录,请先进行登录";
}
String username = this.getStoreUserByUserName(token);
if (username == null || username == ""){
return "登录已失效,请重新登录";
}
if (StringUtils.isNotEmpty(username)){
try {
//在数据库中查询,是否存在响应的账号数据
User user = this.queryByUsername(username);
if (user == null){
return "登录出现异常,请重新登录";
}
}catch (Exception e){
e.printStackTrace();
log.error("服务器出现异常,详细信息为:" + e);
return "服务器出现异常,请稍后重试";
}
}
return null;
}
5.2进行修改密码(controller)
/**
* 修改密码
* @param oldPwd
* @param newPwd
* @param confirmPwd
* @param uid
* @return
*/
@RequestMapping(value = "/modifyPwd")
@ResponseBody
public ResponseEntity<String> modifyPwd(@RequestParam("oldPwd") String oldPwd,
@RequestParam("newPwd") String newPwd,
@RequestParam("confirmPwd") String confirmPwd,
@RequestParam("uid") String uid){
try {
String result = userService.modifyPwd(oldPwd,newPwd,confirmPwd,uid);
if (result != null){
return ResponseEntity.fail(null,result);
}else {
return ResponseEntity.success("密码修改成功,即将跳转到登录页面");
}
}catch (Exception e){
e.printStackTrace();
return ResponseEntity.fail(null,"服务器异常,请稍后再试!");
}
}
5.3在service层进行修改密码逻辑处理
/**
* 密码修改
* @param oldPwd
* @param newPwd
* @param confirmPwd
* @param uid
* @return
*/
@Override
public String modifyPwd(String oldPwd, String newPwd, String confirmPwd, String uid) {
//查询该用户的账号信息
try {
User user = userMapper.selectById(uid);
String password = user.getPassword();
//校验旧密码是否正确
if (oldPwd == null || oldPwd.trim().isEmpty()){
return "密码不能为空";
}else if (oldPwd.length()<5 || oldPwd.length()>15){
return "密码的长度只能在5-15之间";
}else if (!MD5Utils.getEncryptedPwd(oldPwd).equals(password)){
return "密码错误,无法修改密码";
}
//校验新密码格式是否正确
if (newPwd == null || newPwd.trim().isEmpty()){
return "密码不能为空";
}else if (newPwd.length()<5 || newPwd.length()>15){
return "密码的长度只能在5-15之间";
}
//校验确认密码是否和密码一致
if (confirmPwd == null || confirmPwd.trim().isEmpty()){
return "确认密码不能为空";
}else if (!confirmPwd.equals(password)){
return "两次密码不一致";
}
String pwd = MD5Utils.getEncryptedPwd(newPwd);
userMapper.updatePwdById(uid,pwd);
return null;
}catch (Exception e){
e.printStackTrace();
log.error("服务器出现异常,详细信息为:" + e);
return "服务器出现异常,请稍后重试";
}
}
因为DAO层都是简单的增删改查,这里就没有将DAO层代码上传,只上传了controller、service的代码