本博文针对的是开发分布式系统,登录和注册的功能都放到单点登录系统中完成,供其他系统调用。同时,当用户下订单时需要用户登录,使用拦截器实现用户登录。登录成功后跳转到用户要访问的页面。推荐和上一篇《企业WEB项目单点登陆系统实现》一起食用更佳哦。
1、进行注册之前先进行数据的有效性验证。
a) 用户名不能重复
b) 确认密码和密码文本框的内容要一致。
c) 用户名、密码不能为空。
d) 手机不能为空 并且不能重复。
2、校验完成后注册。可以调用sso系统的注册接口完成注册。
@Controller
@RequestMapping("/page")
public class PageController {
@RequestMapping("/register")
public String showRegister() {
return "register";
}
}
回调url应该是通过一个参数传递给显示登录页面的Controller。参数名为:redirect
需要把回调的url传递给jsp页面。当登录成功后,js的逻辑中判断是否有回调的rul,如果有就跳转到此url,如果没有就跳转到商城首页。
@RequestMapping("/login")
public String showLogin(String redirect,Model model) {
model.addAttribute("redirect", redirect);
return "login";
}
校验用户名密码必须输入。
用户点击登录按钮把用户名和密码表单提交给登录接口,接收返回结果判断是否登录成功。
在门户系统点击登录连接跳转到登录页面。登录成功后,跳转到门户系统的首页,在门户系统中需要从cookie中 把token取出来。所以必须在登录成功后把token写入cookie。并且cookie的值必须在系统之间能共享。
1、Domain:必须是相同的。例如有多个域名:
www.taotao.com
Sso.taotao.com
Search.taotao.com
需要设置domain为: .taotao.com
2、设置path:/
package com.taotao.common.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;
}
}
从cookie中取token,在页面中根据token取用户信息,调用sso系统的服务来完成。需要使用jsonp调用。
当用户下订单时需要用户登录,使用拦截器实现用户登录
1、需要实现HandlerInterceptor接口。
2、实现拦截逻辑
3、需要在springmvc.xml中配置。
配置resource.properties
#单点登陆系统url
SSO_BASE_URL=http://localhost:8085
#根据token取用户信息url
SSO_USER_TOKEN=/user/token/
#单点登陆系统登陆url
SSO_PAGE_LOGIN=/page/login
功能:根据token换取用户信息,需要调用sso系统的服务。返回TbUser对象。如果没有就返回null。
@Service
public class UserServiceImpl implements UserService {
@Value("${SSO_BASE_URL}")
public String SSO_BASE_URL;
@Value("${SSO_USER_TOKEN}")
private String SSO_USER_TOKEN;
@Value("${SSO_PAGE_LOGIN}")
public String SSO_PAGE_LOGIN;
@Override
public TbUser getUserByToken(String token) {
try {
//调用sso系统的服务,根据token取用户信息
String json = HttpClientUtil.doGet(SSO_BASE_URL + SSO_USER_TOKEN + token);
//把json转换成TaotaoREsult
TaotaoResult taotaoResult = TaotaoResult.formatToPojo(json, TbUser.class);
if(taotaoResult.getStatus()==200) {
TbUser user = (TbUser) taotaoResult.getData();
return user;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
public class LoginInterceptor implements HandlerInterceptor {
@Autowired
private UserServiceImpl userService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
//在Handler执行之前处理
//判断用户是否登录
//从cookie中取token
String token = CookieUtils.getCookieValue(request, "TT_TOKEN");
//根据token换取用户信息,调用sso系统的接口。
TbUser user = userService.getUserByToken(token);
//取不到用户信息
if(user==null) {
//跳转到登录页面,把用户请求的url作为参数传递给登录页面。
response.sendRedirect(userService.SSO_BASE_URL+userService.SSO_PAGE_LOGIN+"?redirect="+request.getRequestURL());
//返回false
return false;
}
//取到用户信息,放行
//返回值决定Handler是否执行
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
//handler执行之后,返回ModelandView之前
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
//返回ModelandView之后
//响应用户之后。
}
}
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/item/**"/>
<bean class="com.taotao.portal.interceptor.LoginInterceptor"/>
mvc:interceptor>
mvc:interceptors>
我好菜淦