目录
1.用户身份认证
1.1功能分析
1.2拦截器实现
1.3测试访问
2.拦截器存在的问题
2.1解决调用SSO服务两次的问题
2.2解决登录之后跳转到首页的问题
2.3测试访问
在展示订单确认页面之前,需要对用户身份进行认证,要求用户必须登录。
将一些常量放在properties文件中
#cookie中存放token的key
COOKIE_TOKEN_KEY=COOKIE_TOKEN_KEY
#sso服务url
SSO_URL=http://localhost:8088
拦截器是要实现HandlerInterceptor的,我们在taotao-order-web工程的src/main/java目录下新建一个包com.taotao.order.interceptor并在该包下新建LoginInterceptor拦截器(实现HandlerInterceptor)
package com.taotao.order.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.taotao.common.pojo.TaotaoResult;
import com.taotao.common.utils.CookieUtils;
import com.taotao.sso.service.UserLoginService;
public class LoginInterceptor implements HandlerInterceptor {
@Value("${SSO_URL}")
private String SSO_URL;
@Value("${COOKIE_TOKEN_KEY}")
private String COOKIE_TOKEN_KEY;
@Autowired
private UserLoginService loginService;
/**在进入目标方法之前执行*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
//1.从cookie中获取token
String token = CookieUtils.getCookieValue(request, COOKIE_TOKEN_KEY);
if(StringUtils.isEmpty(token)) {
//2.用户未登录,重定向到登陆页面
response.sendRedirect(SSO_URL+"/page/login");
}
TaotaoResult result = loginService.getUserByToken(token);
if(result.getStatus()!=200) {
//3.用户已过期,重定向到登陆页面
response.sendRedirect(SSO_URL+"/page/login");
}else {
//4.用户已登录放行
return true;
}
return false;
}
/**在进入目标方法之后,在返回modelandview之前执行*/
/**共用变量的一些设置*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
/**返回modelandview之后,渲染到页面之前*/
/**异常处理 ,清理工作*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
}
配置拦截器
未登录状态下,结算购物车
被拦截后,重定向到登陆界面
存在两个问题:
实际上,只需要在拦截器中调用一次便可以了,调用之后,将用户信息的数据存放在request域中,等进入目标的方法,可以直接通过request域获取用户信息。
在拦截器中,将登录的用户TbUser对象放到request域中
从request域中获取TbUser对象
当用户结算购物车的时候,需要登录,登录之后应当跳转到订单确认页面,不应该回到首页。
下面是正常的流程
在taotao-sso-web的login.jsp,我们可以看到一个叫做redirectUrl的变量,如果redirectUrl不为空,就会location.href=redirectUrl,
跳转到这个redirectUrl,所以我们可以在拦截器拦截未登录用户跳转http://localhost:8088/page/login时,设置一个参数redirect=http://localhost:8092/order/order-cart.html
比如:
http://localhost:8088/page/login?redirect=http://localhost:8092/order/order-cart.html
然后在taotao-sso-web的controller将redirect接收,并放到model中。
修改taotao-order-web的未登录用户拦截器,在跳转/page/login时加上参数redirect=url
这个地方是request.getRequestURL()不是request.getRequestURI(),小心看走眼
request.getRequestURL()获取请求的全名,包括协议、域名、ip、端口等
request.getRequestURI()只能获取端口后的相对路径
在taotao-sso-web系统中的controller中接收参数redirect,并放到model中
@RequestMapping("/page/{page}")
public String showPage(@PathVariable String page,String redirect,Model model) {
model.addAttribute("redirect", redirect);
return page;
}
启动工程
未登录状态下去结算
可以看到url后面的参数
登录成功跳转到订单确认页