淘淘商城74-商城訂單系統實現之用戶身份認證攔截器與攔截器存在的問題

目錄

1.用戶身份認證

1.1功能分析

1.2攔截器實現

1.3測試訪問

2.攔截器存在的問題

2.1解決調用SSO服務兩次的問題

2.2解決登錄之後跳轉到首頁的問題

2.3測試訪問


1.用戶身份認證

在展示訂單確認頁面之前,需要對用戶身份進行認證,要求用戶必須登錄。

1.1功能分析

  1. 使用springmvc的攔截器實現。需要實現一個接口HandlerInterceptor接口。
  2. 業務邏輯
    1. 從cookie中取token。
    2. 沒有token,需要跳轉到登錄頁面。
    3. 有token。調用sso系統的服務,根據token查詢用戶信息。
    4. 如果查不到用戶信息。用戶登錄已經過期。需要跳轉到登錄頁面。
    5. 查詢到用戶信息。放行。
  3. 在springmvc.xml中配置攔截器。

1.2攔截器實現

將一些常量放在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 {
		
	}

}

配置攔截器

<!-- 配置用戶身份認證的攔截器攔截訂單確認和訂單相關的處理 -->
	<mvc:interceptors>
		<mvc:interceptor>
			<!-- ** 表示當前路徑及其子路徑    * 只是攔截當前路徑-->
			<mvc:mapping path="/order/**"/>
			<bean class="com.taotao.order.interceptor.LoginInterceptor"></bean>
		</mvc:interceptor>
	</mvc:interceptors>

1.3測試訪問

未登錄狀態下,結算購物車

被攔截後,重定向到登陸界面

2.攔截器存在的問題

存在兩個問題:

  1. 調用SSO服務調用了兩次,分別是在攔截器中調用一次,在controller獲取用戶信息又調用一次。
  2. 登錄成功後跳轉到了首頁,應當跳轉到訂單確認頁面纔對。

2.1解決調用SSO服務兩次的問題

實際上,只需要在攔截器中調用一次便可以了,調用之後,將用戶信息的數據存放在request域中,等進入目標的方法,可以直接通過request域獲取用戶信息。

在攔截器中,將登錄的用戶TbUser對象放到request域中

從request域中獲取TbUser對象

2.2解決登錄之後跳轉到首頁的問題

當用戶結算購物車的時候,需要登錄,登錄之後應當跳轉到訂單確認頁面,不應該回到首頁。

下面是正常的流程

在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;
	}

2.3測試訪問

啓動工程

未登錄狀態下去結算

可以看到url後面的參數

登錄成功跳轉到訂單確認頁

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章