後臺判斷請求是否來自微信小程序(SpringBoot攔截器不攔截來自微信小程序的請求)
環境
springboot+微信小程序
背景
開發springboot項目時使用了Interceptor攔截器,用來判斷用戶是否登陸,如果未登錄就訪問項目其他頁面則跳轉登錄頁.
在開發微信小程序時會請求接口,也會被攔截.
解決
思路一
關閉攔截器………
思路二
小程序儲存登陸的cookie.
好像挺麻煩…
思路三
攔截器不攔截來自微信小程序的請求
思路是小程序在request header添加自定義字段,然後攔截器獲取請求頭自定義字段的值,根據值判斷是否放行這個請求
LoginInterceptor.java
package cn.kgc.djz.hangduo.interceptor;
import cn.hutool.core.util.StrUtil;
import cn.kgc.djz.hangduo.controller.UserController;
import cn.kgc.djz.hangduo.model.entity.User;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 攔截器具體操作
*
* @author : djz
* @date : Created in 2020/2/12 23:17
*/
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
/**
* controller方法調用前調用
* 如果未登錄則跳轉登錄頁
*
* @return 往下執行則返回true,否則返回false
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//如果request.getHeader("X-Requested-With") 返回的是"XMLHttpRequest"說明就是ajax請求,需要特殊處理
if ("XMLHttpRequest".equals(request.getHeader("x-requested-with"))) {
log.info("登陸攔截器1執行,請求地址:" + request.getRequestURI() + " AJAX請求放行");
//不攔截ajax請求
return true;
}
if ("true".equals(request.getHeader("isWX"))) {
log.info("登陸攔截器1執行,請求地址:" + request.getRequestURI() + " WX請求放行");
//不攔截微信請求
return true;
}
log.info("登陸攔截器1執行,請求地址:" + request.getRequestURI());
//獲取session中的user
User user = (User) request.getSession().getAttribute("user");
//如果爲空
if (user == null) {
log.info("當前用戶未登錄,跳轉登錄頁面");
//重定向到登陸頁
response.sendRedirect(request.getContextPath() + "tologin");
return false;
} else {
log.info("當前用戶已登錄,登錄的用戶名爲: " + user.getUsername());
}
return true;
}
/**
* controller方法調用後視圖渲染前執行。
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
/**
* controller方法調用且視圖渲染完成後執行
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
InterceptorConfig.java
package cn.kgc.djz.hangduo.config;
import cn.kgc.djz.hangduo.interceptor.LoginInterceptor;
import cn.kgc.djz.hangduo.interceptor.LoginInterceptor2;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 攔截器配置
* <p>
* 過濾器依賴於Servlet容器,而Interceptor則爲SpringMVC的一部分。
* 過濾器能夠攔截所有請求,而Interceptor只能攔截Controller的請求,所以從覆蓋範圍來看,Filter應用更廣一些。
* 但是在Spring逐漸一統Java框架、前後端分離越演越烈,實際上大部分的應用場景,攔截器都可以滿足了。
*
* @author : djz
* @date : Created in 2020/2/12 23:25
*/
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
//需要攔截的路徑,/**表示需要攔截所有請求
String[] addPathPatterns = {"/**"};
//不需要攔截的路徑,當然要包括登錄頁面
String[] excludePathPatterns = {"/tologin", "/dist/**","/error","/toregister","/uploadicon"};
//註冊登錄攔截器
//order指定執行順序,數值越小越優先
//可以配置多個攔截器,給registry再加一個Interceptor就可以了,不用再創建一個新的config配置類。
//攔截器1如果未登錄訪問首頁跳轉登錄頁
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns(addPathPatterns)
.excludePathPatterns(excludePathPatterns)
.order(0);
}
}
controller無需改動
微信小程序
//在需要請求後臺接口的地方添加自定義請求頭
wx.request({
url: 'http://localhost:8080/queryItem',
header: {
'content-type': 'application/json',
//自定義的字段
'isWX': 'true'
},
method: "get",
success: function(res) {
console.log(res.data);
th.setData({
dirList: res.data
});
}
})
效果
值全都獲取到了