现在我主要介绍一下,用户后台登陆系统之后,使用token来校验用户是否合法,使用户信息保持正确。相关代码我已放入下面,有需要的朋友即可尝试一下。
1.首先看到web.xml
<!--配置,解决请求乱码问题-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--自定义拦截器-->
<filter>
<filter-name>myAuthenticationFilter</filter-name>
<filter-class>com.javaclimb.util.filter.MyWebFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myAuthenticationFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2.找到自定义拦截器的MyWebFilter3.
package com.javaclimb.util.filter;
import com.alibaba.druid.support.json.JSONUtils;
import com.javaclimb.util.Consts;
import com.nimbusds.jose.JOSEException;
import com.javaclimb.util.MapWrapperUtils;
import com.javaclimb.util.ReturnData;
import com.javaclimb.util.TextUtils;
import com.javaclimb.util.exception.CustomerException;
import com.javaclimb.util.jwt.JwtUtil;
import org.springframework.web.filter.GenericFilterBean;
import javax.servlet.FilterChain;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*拦截
*/
public class MyWebFilter extends GenericFilterBean {
public static final String FROM_MICRO = "micro";
public static final String USER_TYPE_NORMAL = "userTypeNormal";
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) {
HttpServletRequest req = ((HttpServletRequest) request);
HttpServletResponse resp = ((HttpServletResponse) response);
System.out.println(req.getRequestURL());
List<String> urlIgnorelist = new ArrayList<>();
urlIgnorelist.add("/resources/");
urlIgnorelist.add("/upload/");
urlIgnorelist.add("/requestLogin");
urlIgnorelist.add("/user/getUserByCode");
urlIgnorelist.add("/advertisement/getList");
urlIgnorelist.add("/goods/getList");
urlIgnorelist.add("/goodsType/getList");
urlIgnorelist.add("/login");
urlIgnorelist.add("/regist");
urlIgnorelist.add("/logout");
boolean isNeedDealwith = true;
for (String path : urlIgnorelist) {
if (req.getServletPath().contains(path)) {
isNeedDealwith = false;
break;
}
}
try {
//判断用户的请求来源
String from = req.getHeader("from");
if (TextUtils.isEmpty(from)) {
//web端
if (isNeedDealwith) {
//判断当前用户是否登录
HttpSession session = req.getSession();
Object o = session.getAttribute(Consts.SYS_USER_INFO);
if (o == null) {
resp.sendRedirect(req.getContextPath() + "/login");
} else {
//重新设置,这样就会重新计算失效时间
session.setAttribute(Consts.SYS_USER_INFO, o);
}
}
filterChain.doFilter(req, resp);
} else if (FROM_MICRO.equals(from)) {
//移动端登录
resp.setCharacterEncoding("utf-8");
resp.setContentType("application/json; charset=utf-8");
if (!isNeedDealwith) {
filterChain.doFilter(req, resp);
return;
}
String token = req.getHeader("token");
if (TextUtils.isEmpty(token)) {
makeResponse(resp, ReturnData.fail("请携带token"));
return;
}
ReturnData returnData = JwtUtil.valid(token);
if (returnData.getCode() != 200) {
makeResponse(resp, returnData);
return;
}
Long id = (Long) returnData.getData();
if (id == null) {
makeResponse(resp, ReturnData.fail("token有误"));
return;
}
//利用原始的request对象创建自己扩展的request对象并添加自定义参数
RequestParameterWrapper requestParameterWrapper = new RequestParameterWrapper(req);
Map<String, Object> param = new HashMap<>();
param.put(MapWrapperUtils.KEY_USER_ID, id);
requestParameterWrapper.addParameters(param);
filterChain.doFilter(requestParameterWrapper, resp);
} else {
makeResponse(resp, ReturnData.fail("from参数有误"));
}
} catch (JOSEException e) {
makeResponse(resp, ReturnData.fail("token异常"));
} catch (Exception e) {
Throwable throwable = e.getCause();
System.out.println(throwable.getCause());
if (throwable instanceof CustomerException) {
makeResponse(resp, ReturnData.fail(((CustomerException) throwable).getMsgDes()));
} else {
makeResponse(resp, ReturnData.fail(throwable.getCause() == null ? e.getMessage() : throwable.getCause().getMessage()));
}
}
}
private void makeResponse(HttpServletResponse resp, ReturnData returnData) {
try {
resp.getWriter().print(JSONUtils.toJSONString(returnData));
resp.getWriter().close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3.使用 JwtUtil来判断token是否合法
import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jose.crypto.MACVerifier;
import com.javaclimb.util.MapWrapperUtils;
import com.javaclimb.util.ReturnData;
import com.javaclimb.util.exception.CustomerException;
import net.minidev.json.JSONObject;
import java.text.ParseException;
import java.util.Date;
import java.util.Map;
public class JwtUtil {
/**
* 1.创建一个32-byte的密匙
*/
private static final byte[] secret = "modhfaguafdkslsmxofangsnhpobcewm".getBytes();
//生成一个token
public static String creatToken(Map<String, Object> payloadMap) {
//3.先建立一个头部Header
/**
* JWSHeader参数:1.加密算法法则,2.类型,3.。。。。。。。
* 一般只需要传入加密算法法则就可以。
* 这里则采用HS256
*
* JWSAlgorithm类里面有所有的加密算法法则,直接调用。
*/
JWSHeader jwsHeader = new JWSHeader(JWSAlgorithm.HS256);
//建立一个载荷Payload
Payload payload = new Payload(new JSONObject(payloadMap));
//将头部和载荷结合在一起
JWSObject jwsObject = new JWSObject(jwsHeader, payload);
try {
//建立一个密匙
JWSSigner jwsSigner = new MACSigner(secret);
//签名
jwsObject.sign(jwsSigner);
} catch (JOSEException e) {
throw new CustomerException("toke生成失败");
}
//生成token
return jwsObject.serialize();
}
//解析一个token
public static ReturnData valid(String token) throws ParseException, JOSEException {
ReturnData returnData = null;
// 解析token
JWSObject jwsObject = JWSObject.parse(token);
//获取到载荷
Payload payload = jwsObject.getPayload();
//建立一个解锁密匙
JWSVerifier jwsVerifier = new MACVerifier(secret);
//判断token
if (jwsObject.verify(jwsVerifier)) {
//载荷的数据解析成json对象。
JSONObject jsonObject = payload.toJSONObject();
returnData = ReturnData.success(jsonObject.get(MapWrapperUtils.KEY_USER_ID));
//判断token是否过期
if (jsonObject.containsKey("exp")) {
Long expTime = Long.valueOf(jsonObject.get("exp").toString());
Long nowTime = new Date().getTime();
//判断是否过期
if (nowTime > expTime) {
//已经过期
returnData = ReturnData.fail("登录过期");
}
}
} else {
returnData = ReturnData.fail("token令牌是个假的");
}
return returnData;
}
}
4.MapWrapperUtils相关代码
package com.javaclimb.util;
import java.util.HashMap;
public class MapWrapperUtils extends HashMap<String, Object> {
public static String KEY_USER_ID = "userId";
@Override
public MapWrapperUtils put(String key, Object value) {
super.put(key, value);
return this;
}
public static MapWrapperUtils builder(String key, Object value) {
MapWrapperUtils wrapperUtils = new MapWrapperUtils();
wrapperUtils.put(key, value);
return wrapperUtils;
}
}