SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp

一、单点登录准备工作

1、导入用户表


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第1张图片

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for tb_user
-- ----------------------------
DROP TABLE IF EXISTS `tb_user`;
CREATE TABLE `tb_user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `username` varchar(50) NOT NULL COMMENT '用户名',
  `password` varchar(32) NOT NULL COMMENT '密码,加密存储',
  `phone` varchar(20) DEFAULT NULL COMMENT '注册手机号',
  `email` varchar(50) DEFAULT NULL COMMENT '注册邮箱',
  `created` datetime NOT NULL,
  `updated` datetime NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `username` (`username`) USING BTREE,
  UNIQUE KEY `phone` (`phone`) USING BTREE,
  UNIQUE KEY `email` (`email`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COMMENT='用户表';

2、导入用户的POJO类


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第2张图片


package com.taotao.manager.pojo;

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Table(name = "tb_user")
public class User extends BasePojo {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String username;

    private String password;

    private String phone;

    private String email;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", username=" + username + ", password=" + password + ", phone="
                + phone + ", email=" + email + "]";
    }

}

3、创建UserMapper的接口


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第3张图片


package com.taotao.sso.mapper;

import com.github.abel533.mapper.Mapper;
import com.taotao.manager.pojo.User;

/**
 * 用户的持久层接口
 * @author Administrator
 *
 */
public interface UserMapper extends Mapper {

	
}

4、创建UserService接口和实现类


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第4张图片


package com.taotao.sso.service;

/**
 * 用户的业务层接口
 * 
 * @author Administrator
 *
 */
public interface UserService {

}

package com.taotao.sso.service.impl;

import org.springframework.stereotype.Service;

import com.taotao.sso.service.UserService;

/**
 * 用户业务层实现类
 * @author Administrator
 *
 */
@Service
public class UserServiceImpl implements UserService {

}

5、创建用户的Controller


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第5张图片


package com.taotao.sso.controller;

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

import com.taotao.sso.service.UserService;

/**
 * 用户的Controller
 * @author Administrator
 *
 */
@Controller
@RequestMapping("user")
public class UserController {

	@Autowired
	private UserService userService;
	
}

6、暴露服务和声明服务的调用


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第6张图片


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第7张图片


7、修改host文件和nginx的配置文件


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第8张图片


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第9张图片

二、单点登录接口的实现

1、实现检查数据是否可用

(1)、开发分析

接口文档


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第10张图片


接口是校验username、phone、email三个字段是否可用,用户要输入的这三个字段必须是没有被别人使用过的。

我们可以把这个字段作为条件进行查询,如果查询到了,则表示已经有人用了,那么新用户就不能使用,数据不可用,返回false;如果没有查询到,则表示没有被别人用,新用户可以使用,数据可用,返回true。

(2)、实现Controller

	/**
	 * 校验数据是否可用
	 * 
	 * @param param
	 * @param status
	 * @return
	 */
	@RequestMapping(value = "check/{param}/{type}", method = RequestMethod.GET)
	public ResponseEntity check(@PathVariable String param, @PathVariable Integer type) {
		try {
			Boolean bool = this.userService.check(param, type);
			// 如果成功,返回200
			return ResponseEntity.ok(bool);
		} catch (Exception e) {
			e.printStackTrace();
		}
		// 失败返回500
		return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
	}

(3)、实现Service接口和实现类

UserService.java

package com.taotao.sso.service;

/**
 * 用户的业务层接口
 * 
 * @author Administrator
 *
 */
public interface UserService {

	/**
	 * 校验数据是否可用
	 * 
	 * @param param
	 * @param status
	 * @return
	 */
	public Boolean check(String param, Integer type);

}


UserServicImpl.java
package com.taotao.sso.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.taotao.manager.pojo.User;
import com.taotao.sso.mapper.UserMapper;
import com.taotao.sso.service.UserService;

/**
 * 用户业务层实现类
 * 
 * @author Administrator
 *
 */
@Service
public class UserServiceImpl implements UserService {

	@Autowired
	private UserMapper userMapper;

	/**
	 * 校验数据是否可用
	 * 
	 * @param param
	 * @param status
	 * @return
	 */
	public Boolean check(String param, Integer type) {
		// 声明查询条件
		User user = new User();

		// 设置条件
		switch (type) {
		case 1:
			user.setUsername(param);
			break;
		case 2:
			user.setPhone(param);
			break;
		case 3:
			user.setEmail(param);
			break;
		default:
			break;
		}

		// 执行查询
		Boolean bool = this.userMapper.selectCount(user) == 0;
		
		return bool;
	}

}

2、实现根据ticker查询用户接口

(1)、开发分析


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第11张图片


根据ticket查询用户

用户信息保存在redis中,返回的数据是json格式,需要把json格式数据转为对象

(2)、实现Controller

	/**
	 * 根据ticket查询用户
	 * 
	 * @param ticket
	 * @return
	 */
	@RequestMapping(value = "{ticket}", method = RequestMethod.GET)
	public ResponseEntity queryUserByTicket(@PathVariable String ticket) {
		try {
			User user = this.userService.queryUserByTicket(ticket);
			return ResponseEntity.ok(user);
		} catch (Exception e) {
			e.printStackTrace();
		}
		// 失败返回500
		return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
	}

(3)、实现Service层接口和实现类

	/**
	 * 根据ticket查询用户
	 * 
	 * @param ticket
	 * @return
	 */
	public User queryUserByTicket(String ticket); 


	@Autowired
	private RedisUtils redisUtils;
	
	@Value("${TAOTAO_SSO_TICKET_PRE}")
	private String TAOTAO_SSO_TICKET_PRE;
	
	private static final ObjectMapper MAPPER = new ObjectMapper();
	
	/** 
	 * 根据ticket查询用户 
	 *  
	 * @param ticket 
	 * @return 
	 */  
	public User queryUserByTicket(String ticket) {  
	    //从redis中根据ticket查询用户信息,查询到的是json数据  
	    //需要给redis中的key添加前缀,方便redis的维护和管理  
	    String json = this.redisUtils.get(TAOTAO_SSO_TICKET_PRE + ticket);  
	      
	    //判断json是否为null  
	    if(StringUtils.isNotBlank(json)){  
		try {  
		    //把json转换为对象  
		    User user = MAPPER.readValue(json, User.class);  
		      
		    //如果用户调用该方法,表示用户是活动的,需要重新设置redis中用户的缓存时间,避免每隔固定时间,用户就要重新登录  
		    this.redisUtils.expire(TAOTAO_SSO_TICKET_PRE + ticket, 60*30);  
		      
		    //返回用户对象  
		    return user;  
		} catch (Exception e) {  
		    e.printStackTrace();  
		}  
	    }  
	    //如果没有查询到数据,或者转换异常,返回null  
	    return null;  
	} 

(4)、在redis资源配置文件中配置前缀

#配置redis中用户数据前缀
TAOTAO_SSO_TICKET_PRE=TAOTAO_SSO_TICKET_PRE_


三、首页跳转注册、登录页面

1、在taotao-portal中编写通用页面跳转的Controller代码


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第12张图片


package com.taotao.portal.controller;

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;

/**
 * 通用页面跳转方法
 * 
 * @author Administrator
 *
 */
@Controller
@RequestMapping("page")
public class PageController {

	/**
	 * 通用页面跳转的方法
	 * 
	 * @param pageName
	 * @return
	 */
	@RequestMapping(value = "{pageName}", method = RequestMethod.GET)
	public String toPage(@PathVariable String pageName) {
		return pageName;
	}
}


四、jsonp

1、jsonp在项目中应用的位置

(1)、查看发送ajax请求的url


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第13张图片


(2)、在项目中搜索 /user/check 的ajax 所在位置


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第14张图片


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第15张图片


(3)、查看ajax逻辑,找到 jsonp 所在位置


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第16张图片


分析:

分析发现使用的dataType是jsonp,这里使用的是jsonp技术

为什么要使用jsonp呢,这里使用jsonp是为了解决js跨域调用的问题。

2、跨域问题

(1)、什么是跨域

跨域就是跨域名或跨端口号进行调用,例如:

www.taotao.com >> www.jd.com 是跨域

www.taotao.com >> sso.taotao.com 是跨域

www.taotao.com >> www.taotao.com:8080         是跨域

www.taotao.com >> www.taotao.com 不是跨域

只有请求者和被请求者的域名和端口号完全一致,才不是跨域

(2)、跨域有什么问题

js使用Ajax请求进行跨域请求,无法返回数据(json、xml等)。

(3)、为什么会有跨域问题

浏览器基于安全考虑,不允许Ajax请求跨域调用数据(json、xml等)

我们现在碰到的问题就是,www.taotao.com请求sso.taotao.com,因为跨域问题,是无法使用Ajax获取数据的

3、jsonp原理

(1)、jsonp核心原理

js使用Ajax无法跨域调用数据(xml,json等),但是可以跨域调用js数据,js的Ajax请求数据和请求js数据的不同如下图:


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第17张图片


(2)、解决js使用Ajax无法跨域获取数据的方法

我们可以通过请求js的方式,进行跨域调用,如下图:


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第18张图片


五、单点登录支持jsonp

1、分析

修改单点登录接口,使其支持跨域其实就是使用request获取方法名,再把返回值进行包裹。

我们需要做的事,如下图:


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第19张图片


分析发现,我们需要的请求参数名其实就是callback


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第20张图片

2、改造UserController.java代码


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第21张图片


	/**
	 * 校验数据是否可用
	 * 
	 * @param param
	 * @param status
	 * @return
	 */
	@RequestMapping(value = "check/{param}/{type}", method = RequestMethod.GET)
	public ResponseEntity check(String callback, @PathVariable String param, @PathVariable Integer type) {
		try {
			
			Boolean bool = this.userService.check(param, type);
			//1.接收请求中的callback的值
			//2.判断callback是否为null,如果为null,则表示是普通的访问
			String result = "";
			if(StringUtils.isNotBlank(callback)){
				//如果部位null,表示是jsonp请求
				//3.使用callback包裹返回的json数据,实现跨域调用
				result = callback + "(" + bool +")";
			}else{
				//不是jsonp请求,直接返回数据
				result = "" + bool;
			}
			// 如果成功,返回200
			return ResponseEntity.ok(result);
		} catch (Exception e) {
			e.printStackTrace();
		}
		// 失败返回500
		return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
	}

3、测试效果页面


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第22张图片


六、实现用户注册

1、改造页面注册方法的请求url


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第23张图片


2、编写用户登录的Controller

(1)、在taotao-portal中加入sso-interface的依赖


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第24张图片


(2)、在taotao-portal中编写UserConterller.java

package com.taotao.portal.controller;

import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
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 com.taotao.manager.pojo.User;
import com.taotao.sso.service.UserService;

/**
 * 用户功能的web类
 * 
 * @author Administrator
 *
 */
@Controller
@RequestMapping("user")
public class UserController {

	@Autowired
	private UserService userService;

	/**
	 * 用户注册的方法
	 * 
	 * @param user
	 * @return
	 */
	@RequestMapping(value = "doRegister", method = RequestMethod.POST)
	@ResponseBody
	public Map register(User user) {
		this.userService.saveUser(user);
		Map map = new HashMap();
		map.put("status", 200);
		return map;
	}
}

3、在portal系统中声明服务的调用


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第25张图片


4、编写UserService层接口和实现类

	/**
	 * 用户注册的方法
	 * 
	 * @param user
	 */
	public void saveUser(User user);

	/**
	 * 用户注册的方法
	 */
	public void saveUser(User user) {
		// 设置用户信息
		user.setCreated(new Date());
		user.setUpdated(user.getCreated());
		// 需要对密码进行加密,加密方法用的是md5Hex(),DigestUtils是commons-codecjar包中的方法
		user.setPassword(DigestUtils.md5Hex(user.getPassword()));

		// 执行保存方法
		this.userMapper.insert(user);
	}

5、测试注册

发现问题:数据保存成功,但页面返回值错误




SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第26张图片


问题分析:

springmvc底层机制是如果请求路径以.html结尾,系统默认以html的方式响应


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第27张图片


问题解决:修改portal项目中web.xml中拦截的路径,添加 /service/* 的拦截路径


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第28张图片


同时:修改注册js的url


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第29张图片


修改之后从新启动portal项目测试


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第30张图片


七、实现用户登录

1、登录页面的代码分析


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第31张图片


2、导入操作Cookie的工具类


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第32张图片


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第33张图片


package com.taotao.portal.utils;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;

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


/**
 * 
 * Cookie 工具类
 *
 */
public final class CookieUtils {

    /**
     * 得到Cookie的值, 不编码
     * 
     * @param request
     * @param cookieName
     * @return
     */
    public static String getCookieValue(HttpServletRequest request, String cookieName) {
        return getCookieValue(request, cookieName, false);
    }

    /**
     * 得到Cookie的值,
     * 
     * @param request
     * @param cookieName
     * @return
     */
    public static String getCookieValue(HttpServletRequest request, String cookieName, boolean isDecoder) {
        Cookie[] cookieList = request.getCookies();
        if (cookieList == null || cookieName == null) {
            return null;
        }
        String retValue = null;
        try {
            for (int i = 0; i < cookieList.length; i++) {
                if (cookieList[i].getName().equals(cookieName)) {
                    if (isDecoder) {
                        retValue = URLDecoder.decode(cookieList[i].getValue(), "UTF-8");
                    } else {
                        retValue = cookieList[i].getValue();
                    }
                    break;
                }
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return retValue;
    }

    /**
     * 得到Cookie的值,
     * 
     * @param request
     * @param cookieName
     * @return
     */
    public static String getCookieValue(HttpServletRequest request, String cookieName, String encodeString) {
        Cookie[] cookieList = request.getCookies();
        if (cookieList == null || cookieName == null) {
            return null;
        }
        String retValue = null;
        try {
            for (int i = 0; i < cookieList.length; i++) {
                if (cookieList[i].getName().equals(cookieName)) {
                    retValue = URLDecoder.decode(cookieList[i].getValue(), encodeString);
                    break;
                }
            }
        } catch (UnsupportedEncodingException e) {
        	 e.printStackTrace();
        }
        return retValue;
    }

    /**
     * 设置Cookie的值 不设置生效时间默认浏览器关闭即失效,也不编码
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
            String cookieValue) {
        setCookie(request, response, cookieName, cookieValue, -1);
    }

    /**
     * 设置Cookie的值 在指定时间内生效,但不编码
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
            String cookieValue, int cookieMaxage) {
        setCookie(request, response, cookieName, cookieValue, cookieMaxage, false);
    }

    /**
     * 设置Cookie的值 不设置生效时间,但编码
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
            String cookieValue, boolean isEncode) {
        setCookie(request, response, cookieName, cookieValue, -1, isEncode);
    }

    /**
     * 设置Cookie的值 在指定时间内生效, 编码参数
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
            String cookieValue, int cookieMaxage, boolean isEncode) {
        doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, isEncode);
    }

    /**
     * 设置Cookie的值 在指定时间内生效, 编码参数(指定编码)
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
            String cookieValue, int cookieMaxage, String encodeString) {
        doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, encodeString);
    }

    /**
     * 删除Cookie带cookie域名
     */
    public static void deleteCookie(HttpServletRequest request, HttpServletResponse response,
            String cookieName) {
        doSetCookie(request, response, cookieName, "", -1, false);
    }

    /**
     * 设置Cookie的值,并使其在指定时间内生效
     * 
     * @param cookieMaxage cookie生效的最大秒数
     */
    private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response,
            String cookieName, String cookieValue, int cookieMaxage, boolean isEncode) {
        try {
            if (cookieValue == null) {
                cookieValue = "";
            } else if (isEncode) {
                cookieValue = URLEncoder.encode(cookieValue, "utf-8");
            }
            Cookie cookie = new Cookie(cookieName, cookieValue);
            if (cookieMaxage > 0)
                cookie.setMaxAge(cookieMaxage);
            if (null != request) {// 设置域名的cookie
            	String domainName = getDomainName(request);
            	System.out.println(domainName);
                if (!"localhost".equals(domainName)) {
                	cookie.setDomain(domainName);
                }
            }
            cookie.setPath("/");
            response.addCookie(cookie);
        } catch (Exception e) {
        	 e.printStackTrace();
        }
    }

    /**
     * 设置Cookie的值,并使其在指定时间内生效
     * 
     * @param cookieMaxage cookie生效的最大秒数
     */
    private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response,
            String cookieName, String cookieValue, int cookieMaxage, String encodeString) {
        try {
            if (cookieValue == null) {
                cookieValue = "";
            } else {
                cookieValue = URLEncoder.encode(cookieValue, encodeString);
            }
            Cookie cookie = new Cookie(cookieName, cookieValue);
            if (cookieMaxage > 0)
                cookie.setMaxAge(cookieMaxage);
            if (null != request) {// 设置域名的cookie
            	String domainName = getDomainName(request);
            	System.out.println(domainName);
                if (!"localhost".equals(domainName)) {
                	cookie.setDomain(domainName);
                }
            }
            cookie.setPath("/");
            response.addCookie(cookie);
        } catch (Exception e) {
        	 e.printStackTrace();
        }
    }

    /**
     * 得到cookie的域名
     */
    private static final String getDomainName(HttpServletRequest request) {
        String domainName = null;

        String serverName = request.getRequestURL().toString();
        if (serverName == null || serverName.equals("")) {
            domainName = "";
        } else {
            serverName = serverName.toLowerCase();
            serverName = serverName.substring(7);
            final int end = serverName.indexOf("/");
            serverName = serverName.substring(0, end);
            final String[] domains = serverName.split("\\.");
            int len = domains.length;
            if (len > 3) {
                // www.xxx.com.cn
                domainName = "." + domains[len - 3] + "." + domains[len - 2] + "." + domains[len - 1];
            } else if (len <= 3 && len > 1) {
                // xxx.com or xxx.cn
                domainName = "." + domains[len - 2] + "." + domains[len - 1];
            } else {
                domainName = serverName;
            }
        }

        if (domainName != null && domainName.indexOf(":") > 0) {
            String[] ary = domainName.split("\\:");
            domainName = ary[0];
        }
        return domainName;
    }

}

3、编写登录的Controller代码

SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第34张图片

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

	/**
	 * 用户登录的方法
	 * 
	 * @param username
	 * @param password
	 * @return
	 */
	@RequestMapping(value = "doLogin", method = RequestMethod.POST)
	@ResponseBody
	public Map doLogin(HttpServletRequest request, HttpServletResponse response, String username,
			String password) {
		// 调用服务,登录用户,返回登录成功所需要的ticket
		String ticket = this.userService.doLogin(username, password);

		// 创建集合,存放返回数据
		Map map = new HashMap();

		// 判断ticket是否为null
		if (StringUtils.isNotBlank(ticket)) {
			// 不为空,把ticket放入cookie中
			CookieUtils.setCookie(request, response, this.COOKIE_TICKET, ticket, 60 * 60 * 24, true);
			// 封装返回数据
			map.put("status", 200);
		} else {
			// 为空,登录失败,返回结果中不存放任何数据
		}

		return map;
	}

4、配置env.properties资源文件中的cookie的name值


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第35张图片


5、编写Service层接口和实现类

	/**
	 * 用户登录的方法
	 * 
	 * @param user
	 */
	public String doLogin(String username, String password);

	@Value("${TAOTAO_SSO_TICKET_INCR}")
	private String TAOTAO_SSO_TICKET_INCR;
	/**
	 * 用户登录的方法
	 */
	public String doLogin(String username, String password) {
		//声明查询条件
		User user = new User();
		user.setUsername(username);
		user.setPassword(DigestUtils.md5Hex(password));
		
		//根据用户名密码执行查询方法
		User result = this.userMapper.selectOne(user);
		
		//判断用户是否登录成功
		if(result != null){
			//利用redis单线程的特点,生成唯一的标识ticket   ticket=随机数+用户id
			long incr = this.redisUtils.incr(this.TAOTAO_SSO_TICKET_INCR);
			String ticket = String.valueOf(incr) + result.getId();
			
			//把ticket和用户信息保存到redis中
			try {
				this.redisUtils.set(TAOTAO_SSO_TICKET_PRE + ticket, MAPPER.writeValueAsString(result),60 * 30);
				//返回数据
				return ticket;
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return null;
	}

6、在sso-service中配置资源文件


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第36张图片


7、测试用户登录,并且查看是否把ticket存入cookie中

问题出现:可以登录成功,但是cookies中没有ticket的cookie


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第37张图片


问题原因:使用debug查看存储cookie过程中,获取的域名为127.0.0.1


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第38张图片


问题分析:因为nginx反向代理的时候,没有携带域名

8、解决无法把ticket存入cookie中的问题

在nginx配置文件中加上域名的反向代理


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第39张图片

9、测试查看是否有cookie


SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp_第40张图片

你可能感兴趣的:(ssm项目实战)