飞滴出行网约车2022-乘客服务 redis存储token并使用拦截器进行的校验

master
yh 3 years ago
parent aba6820dac
commit c87c7bb993

@ -1,5 +1,6 @@
package com.mashibing.apipassenger.interceptor; package com.mashibing.apipassenger.interceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@ -7,12 +8,21 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration @Configuration
public class InterceptorConfig implements WebMvcConfigurer { public class InterceptorConfig implements WebMvcConfigurer {
@Bean
public JwtInterceptor jwtInterceptor(){
return new JwtInterceptor();
}
@Override @Override
public void addInterceptors(InterceptorRegistry registry) { public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new JwtInterceptor()) registry.addInterceptor(jwtInterceptor())
// 拦截所有路径 // 拦截所有路径
.addPathPatterns("/**") .addPathPatterns("/**")
// 部份取消拦截路径 // 部份取消拦截路径
.excludePathPatterns(("/noauthTest")); .excludePathPatterns(
("/noauthTest")
,("/verification-code")
,("/verification-code-check")
);
} }
} }

@ -4,8 +4,12 @@ import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.SignatureVerificationException; import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException; import com.auth0.jwt.exceptions.TokenExpiredException;
import com.mashibing.internalcommon.dto.ResponseResult; import com.mashibing.internalcommon.dto.ResponseResult;
import com.mashibing.internalcommon.dto.TokenResult;
import com.mashibing.internalcommon.util.JwtUtils; import com.mashibing.internalcommon.util.JwtUtils;
import net.sf.json.JSONObject; import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@ -14,15 +18,30 @@ import java.io.PrintWriter;
public class JwtInterceptor implements HandlerInterceptor { public class JwtInterceptor implements HandlerInterceptor {
@Autowired
private StringRedisTemplate redisTemplate;
@Override @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 返回 结果是否通过
boolean result = true; boolean result = true;
// 返回 信息字符串
String resutltString = "" ; String resutltString = "" ;
String token = request.getHeader ( "Authorization") ;
String token = null;
TokenResult tokenResult = null;
try { try {
JwtUtils.parseToken(token); token = request.getHeader ( "Authorization") ;
}catch (Exception e) {
resutltString = "Header Must param get Error";
result = false;
}
try {
// 判断是否 token 是否能合法解析
tokenResult = JwtUtils.parseToken(token);
}catch (SignatureVerificationException e){ }catch (SignatureVerificationException e){
resutltString="token sign error"; resutltString="token sign error";
result=false; result=false;
@ -33,10 +52,43 @@ public class JwtInterceptor implements HandlerInterceptor {
resutltString="token AlgorithmMismatchException"; resutltString="token AlgorithmMismatchException";
result=false; result=false;
}catch (Exception e) { }catch (Exception e) {
resutltString = "token invalid"; resutltString = "token gotError";
result = false; result = false;
} }
if(! StringUtils.isBlank(token)){
// 判断 解析传入token
if (tokenResult == null ) {
resutltString = "token invalid ";
result = false;
}else{
String phone = tokenResult.getPhone();
String indentiny = tokenResult.getIndentiny();
// 从redis中取出token
String rdisTokenKey = JwtUtils.getRdisTokenKey(phone, indentiny);
String redisToken = redisTemplate.opsForValue().get(rdisTokenKey);
// 判断 redis 中是否存在值
if(StringUtils.isBlank(redisToken) ){
resutltString = "token invalid ";
result = false;
}
if(!StringUtils.equals(token.trim(),redisToken.trim())){
resutltString = "token Has invalid ";
result = false;
}else{
resutltString = "token verfiy pass ";
result = true;
}
}
}else{
resutltString = "token invalid ";
result = false;
}
// 当 token 获取异常,则向前端输出 失败
if (!result){ if (!result){
PrintWriter out = response.getWriter(); PrintWriter out = response.getWriter();
out.print(JSONObject.fromObject( ResponseResult.fail(resutltString) ).toString()); out.print(JSONObject.fromObject( ResponseResult.fail(resutltString) ).toString());

@ -9,12 +9,12 @@ import com.mashibing.internalcommon.request.VerificationCodeDTO;
import com.mashibing.internalcommon.response.NumberCodeResponse; import com.mashibing.internalcommon.response.NumberCodeResponse;
import com.mashibing.internalcommon.response.TokenResponse; import com.mashibing.internalcommon.response.TokenResponse;
import com.mashibing.internalcommon.util.JwtUtils; import com.mashibing.internalcommon.util.JwtUtils;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.time.Duration;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@Service @Service
@ -26,13 +26,9 @@ public class VerificationCodeService {
@Autowired @Autowired
private ServicePassengerUserCLient servicePassengerUserCLient; private ServicePassengerUserCLient servicePassengerUserCLient;
@Autowired @Autowired
private StringRedisTemplate redisTemplate; private StringRedisTemplate redisTemplate;
private String prefixKey = "passenger-verification-code-";
/** /**
* redis * redis
@ -46,7 +42,7 @@ public class VerificationCodeService {
String numberCode = numberCodeResponse.getData().getNumberCode(); String numberCode = numberCodeResponse.getData().getNumberCode();
// 存入redis // 存入redis
String redisKey = getRdisKey(passengerPhone); String redisKey = JwtUtils.getRdisVeriCodeKey(passengerPhone);
redisTemplate.opsForValue().set(redisKey,numberCode,2, TimeUnit.MINUTES); redisTemplate.opsForValue().set(redisKey,numberCode,2, TimeUnit.MINUTES);
// 返回处理结果 // 返回处理结果
@ -62,8 +58,8 @@ public class VerificationCodeService {
public ResponseResult checkCode(String passengerPhone,String verificationCode){ public ResponseResult checkCode(String passengerPhone,String verificationCode){
// 根据 key前缀+号码 从redis取出对应 校验码比较 // 根据 key前缀+号码 从redis取出对应 校验码比较
String redisKey = getRdisKey(passengerPhone); String redisVeriCodeKey = JwtUtils.getRdisVeriCodeKey(passengerPhone);
String codeRedis = redisTemplate.opsForValue().get(redisKey); String codeRedis = redisTemplate.opsForValue().get(redisVeriCodeKey);
// 校验 验证码 是否相同 // 校验 验证码 是否相同
if(StringUtils.isBlank(codeRedis) || !StringUtils.equals(codeRedis,verificationCode) ){ if(StringUtils.isBlank(codeRedis) || !StringUtils.equals(codeRedis,verificationCode) ){
@ -74,10 +70,15 @@ public class VerificationCodeService {
VerificationCodeDTO verificationCodeDTO = new VerificationCodeDTO(); VerificationCodeDTO verificationCodeDTO = new VerificationCodeDTO();
verificationCodeDTO.setPassengerPhone(passengerPhone); verificationCodeDTO.setPassengerPhone(passengerPhone);
servicePassengerUserCLient.loginOrRegister(verificationCodeDTO); servicePassengerUserCLient.loginOrRegister(verificationCodeDTO);
redisTemplate.delete(redisKey);// 使用后删除key redisTemplate.opsForValue().set(redisVeriCodeKey,"");
Boolean delete = redisTemplate.delete(redisVeriCodeKey);// 使用后删除key
// 颁布 token 令牌 // 颁布 token 令牌
String token = JwtUtils.gerneratorToken(passengerPhone, IndentinyConstant.PASSENGER_IDENTITY); String token = JwtUtils.gerneratorToken(passengerPhone, IndentinyConstant.PASSENGER_IDENTITY);
// 将 token 存入 redis 中
String redisTokenKey = JwtUtils.getRdisTokenKey(passengerPhone, IndentinyConstant.PASSENGER_IDENTITY);
redisTemplate.opsForValue().set(redisTokenKey,token,30,TimeUnit.DAYS);
TokenResponse tokenResponse = new TokenResponse(); TokenResponse tokenResponse = new TokenResponse();
tokenResponse.setToken(token); tokenResponse.setToken(token);
@ -85,8 +86,5 @@ public class VerificationCodeService {
return ResponseResult.success(tokenResponse); return ResponseResult.success(tokenResponse);
} }
private String getRdisKey(String passengerPhone){
return prefixKey.trim() + passengerPhone.trim();
}
} }

@ -20,16 +20,18 @@ public class JwtUtils {
private static final String JWT_KEY_INDENTINY = "indentiny"; private static final String JWT_KEY_INDENTINY = "indentiny";
private static final String veriCodePrefix = "passenger-verification-code-";
private static final String tokenPrefix = "passenger-verification-code-";
/** /**
* token * token
*/ */
public static String gerneratorToken(String passengerPhone,String indentiny){ public static String gerneratorToken(String passengerPhone,String indentiny){
// 准备 token过期时间 Date 类型 // // 准备 token过期时间 Date 类型 -移交服务端进行控制
Calendar calendar = Calendar.getInstance(); // Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE,1); // calendar.add(Calendar.DATE,1);
Date date = calendar.getTime(); // Date date = calendar.getTime();
// 使用 JWT 创建 token合成对象 builder // 使用 JWT 创建 token合成对象 builder
JWTCreator.Builder builder = JWT.create(); JWTCreator.Builder builder = JWT.create();
@ -38,8 +40,8 @@ public class JwtUtils {
builder.withClaim(JWT_KEY_PHONE,passengerPhone); builder.withClaim(JWT_KEY_PHONE,passengerPhone);
builder.withClaim(JWT_KEY_INDENTINY,indentiny); builder.withClaim(JWT_KEY_INDENTINY,indentiny);
// 设置 超时时间 // 设置 超时时间 -移交服务端进行控制
builder.withExpiresAt(date); // builder.withExpiresAt(date);
// 使用 builder对象的 sign 方法生成 token // 使用 builder对象的 sign 方法生成 token
String sign = builder.sign(Algorithm.HMAC256(SIGN)); String sign = builder.sign(Algorithm.HMAC256(SIGN));
@ -48,7 +50,7 @@ public class JwtUtils {
} }
/** /**
* token * token
* @param token * @param token
* @return * @return
*/ */
@ -56,8 +58,8 @@ public class JwtUtils {
// 通过 JWT 的 required 以某种加密算法校验后 进行比对 // 通过 JWT 的 required 以某种加密算法校验后 进行比对
DecodedJWT verify = JWT.require(Algorithm.HMAC256(SIGN)).build().verify(token); DecodedJWT verify = JWT.require(Algorithm.HMAC256(SIGN)).build().verify(token);
// 获取有效数据内容 // 获取有效数据内容
String phone = verify.getClaim(JWT_KEY_PHONE).toString(); String phone = verify.getClaim(JWT_KEY_PHONE).asString();
String indentiny = verify.getClaim(JWT_KEY_INDENTINY).toString(); String indentiny = verify.getClaim(JWT_KEY_INDENTINY).asString();
TokenResult result = new TokenResult(); TokenResult result = new TokenResult();
result.setPhone(phone); result.setPhone(phone);
@ -66,7 +68,14 @@ public class JwtUtils {
return result; return result;
} }
// 获取 验证码存入redis中的 key
public static String getRdisVeriCodeKey(String passengerPhone){
return veriCodePrefix.trim() + passengerPhone.trim();
}
// 获取 token 存入redis中的 key
public static String getRdisTokenKey(String phone,String indentiny){
return tokenPrefix.trim() + phone.trim() + indentiny.trim();
}
// public static void main (String [ ] args ) { // public static void main (String [ ] args ) {
// //

Loading…
Cancel
Save