https://blog.csdn.net/qq_36085004/article/details/83348144
2018年10月24日 17:59:29 PerkinsLi 阅读数:232
文章目录
API校验
在前后端分离开发时,后端获取数据就是通过异步请求调我们的API接口,但是,如果我们不做安全处理,其他人也可以直接调我们的API,这会让我们的数据泄露。因此,为了让我们的API只能被我们允许的人调用,我们对我们的API进行安全处理,他人在调用我们的API时需要进行校验,符合的才允许调用API。
客户端:
调用我们API的人需要用时间戳timestamp,随机字符串noncestr,请求参数以升序排列拼接成一个字符串,并使用MD5进行加密生成一个签名sign。
在发送请求时,将timestamp, noncestr,sign发送给后台
后台:
编写一个拦截器,将所有的请求拦截。
在拦截器中进行请求校验:
1,请求参数sign是否为空,为空返回false。
2,timestamp 加十分钟(超过10分钟请求过期)是否小于服务端当前时间戳,小于返回false。
3,后台获取所有参数,以同样的规则拼接字符串,使用MD5加密,得到一个签名,用得到的签名和请求传来的签名进行比较,相同则放行,不同返回false。
<span style="color:rgba(0, 0, 0, 0.75)"><span style="color:#000000"><code class="language-Java">package com.xyy.edlp.intercepter;
import org.springframework.util.DigestUtils;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
/**
* @Author: perkins
*/
public class ApiSignatureInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
Enumeration<String> paramNames = request.getParameterNames();
String timestamp = request.getHeader("timestamp");
long timestampDate = Long.valueOf(timestamp) + 1000*60*10;
long currDate = System.currentTimeMillis();
// 请求过期
if (timestampDate < currDate) {
response.setStatus(403);
return false;
}
String noncestr = request.getHeader("noncestr");
String signature = request.getParameter("sign");
System.out.println(signature);
if (signature == null) {
response.setStatus(403);
return false;
}
Map map = new HashMap();
//获取所有的请求参数
while (paramNames.hasMoreElements()) {
String paramName = paramNames.nextElement();
String[] paramValues = request.getParameterValues(paramName);
if (paramValues.length > 0) {
String paramValue = paramValues[0];
System.out.println(paramName);
if (paramValue.length() != 0 && !"sign".equals(paramName)) {
map.put(paramName, paramValue);
}
}
}
Set setKey = map.keySet();
Object[] keys = setKey.toArray();
// 将请求参数升序排序
Arrays.sort(keys);
StringBuilder strBuilder = new StringBuilder();
for (Object str : keys) {
strBuilder.append(str.toString());
strBuilder.append(map.get(str.toString()));
}
strBuilder.append("noncestr");
strBuilder.append(noncestr);
strBuilder.append("timestamp");
strBuilder.append(timestamp);
System.out.println(strBuilder.toString());
String newSignature = DigestUtils.md5DigestAsHex(strBuilder.toString().getBytes()).toUpperCase();
if (!signature.equals(newSignature)) {
response.setStatus(403);
return false;
}
return true;
}
}
</code></span></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
<span style="color:rgba(0, 0, 0, 0.75)"><span style="color:#000000"><code class="language-Java">@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry){
registry.addInterceptor(new ApiSignatureInterceptor());
}
}
</code></span></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
登录token权限验证
系统中,有的api必须用户登陆了才能够调用,因此,必须给这样的api进行安全防护。
1,客户端调用登录接口,登录成功,使用JWT生成一个token,将token以UID—token键值对的形式存入redis,返回给客户端一个token和UID。
2,创建一个拦截器,对需要登录权限的接口进行拦截,判断请求中是否有token,根据UID从redis中取出对应的token,对请求中的token进行验证,然后再使用JWT验证token,都没问题放行,否则返回false。
<span style="color:rgba(0, 0, 0, 0.75)"><span style="color:#000000"><code class="language-java"><span style="color:#c678dd">package</span> com<span style="color:#999999">.</span>xyy<span style="color:#999999">.</span>edlp<span style="color:#999999">.</span>util<span style="color:#999999">;</span>
<span style="color:#c678dd">import</span> com<span style="color:#999999">.</span>auth0<span style="color:#999999">.</span>jwt<span style="color:#999999">.</span>JWT<span style="color:#999999">;</span>
<span style="color:#c678dd">import</span> com<span style="color:#999999">.</span>auth0<span style="color:#999999">.</span>jwt<span style="color:#999999">.</span>JWTVerifier<span style="color:#999999">;</span>
<span style="color:#c678dd">import</span> com<span style="color:#999999">.</span>auth0<span style="color:#999999">.</span>jwt<span style="color:#999999">.</span>algorithms<span style="color:#999999">.</span>Algorithm<span style="color:#999999">;</span>
<span style="color:#c678dd">import</span> com<span style="color:#999999">.</span>auth0<span style="color:#999999">.</span>jwt<span style="color:#999999">.</span>exceptions<span style="color:#999999">.</span>JWTDecodeException<span style="color:#999999">;</span>
<span style="color:#c678dd">import</span> com<span style="color:#999999">.</span>auth0<span style="color:#999999">.</span>jwt<span style="color:#999999">.</span>interfaces<span style="color:#999999">.</span>DecodedJWT<span style="color:#999999">;</span>
<span style="color:#c678dd">import</span> java<span style="color:#999999">.</span>io<span style="color:#999999">.</span>UnsupportedEncodingException<span style="color:#999999">;</span>
<span style="color:#c678dd">import</span> java<span style="color:#999999">.</span>util<span style="color:#999999">.</span>Date<span style="color:#999999">;</span>
<span style="color:#5c6370">/**
* @Author: perkins
*/</span>
<span style="color:#c678dd">public</span> <span style="color:#c678dd">class</span> JwtUtil <span style="color:#999999">{</span>
<span style="color:#c678dd">private</span> <span style="color:#c678dd">static</span> <span style="color:#c678dd">final</span> String encodeSecretKey <span style="color:#669900">=</span> <span style="color:#669900">"XX#$%()(#*!()!KL<><MQLMNQNQJQKsdfkjsdrow32234545fdf>?N<:{LWPW"</span><span style="color:#999999">;</span>
<span style="color:#5c6370">/**
* token过期时间
*/</span>
<span style="color:#c678dd">private</span> <span style="color:#c678dd">static</span> <span style="color:#c678dd">final</span> <span style="color:#c678dd">long</span> EXPIRE_TIME <span style="color:#669900">=</span> <span style="color:#98c379">1000</span> <span style="color:#669900">*</span> <span style="color:#98c379">60</span> <span style="color:#669900">*</span> <span style="color:#98c379">60</span> <span style="color:#669900">*</span> <span style="color:#98c379">24</span> <span style="color:#669900">*</span> <span style="color:#98c379">7</span><span style="color:#999999">;</span>
<span style="color:#5c6370">/**
* 生成token
* @return
*/</span>
<span style="color:#c678dd">public</span> <span style="color:#c678dd">static</span> String <span style="color:#61aeee">createToken</span><span style="color:#999999">(</span>String account<span style="color:#999999">)</span> <span style="color:#999999">{</span>
<span style="color:#c678dd">try</span> <span style="color:#999999">{</span>
Date date <span style="color:#669900">=</span> <span style="color:#c678dd">new</span> Date<span style="color:#999999">(</span>System<span style="color:#999999">.</span><span style="color:#61aeee">currentTimeMillis</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#669900">+</span> EXPIRE_TIME<span style="color:#999999">)</span><span style="color:#999999">;</span>
Algorithm algorithm <span style="color:#669900">=</span> Algorithm<span style="color:#999999">.</span><span style="color:#61aeee">HMAC256</span><span style="color:#999999">(</span>account <span style="color:#669900">+</span> encodeSecretKey<span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#c678dd">return</span> JWT<span style="color:#999999">.</span><span style="color:#61aeee">create</span><span style="color:#999999">(</span><span style="color:#999999">)</span>
<span style="color:#999999">.</span><span style="color:#61aeee">withExpiresAt</span><span style="color:#999999">(</span>date<span style="color:#999999">)</span>
<span style="color:#999999">.</span><span style="color:#61aeee">withClaim</span><span style="color:#999999">(</span><span style="color:#669900">"account"</span><span style="color:#999999">,</span> account<span style="color:#999999">)</span>
<span style="color:#999999">.</span><span style="color:#61aeee">sign</span><span style="color:#999999">(</span>algorithm<span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span> <span style="color:#c678dd">catch</span> <span style="color:#999999">(</span>UnsupportedEncodingException e<span style="color:#999999">)</span> <span style="color:#999999">{</span>
<span style="color:#c678dd">return</span> null<span style="color:#999999">;</span>
<span style="color:#999999">}</span>
<span style="color:#999999">}</span>
<span style="color:#5c6370">/**
* 校验token是否失效
* @param token
* @return
*/</span>
<span style="color:#c678dd">public</span> <span style="color:#c678dd">static</span> <span style="color:#c678dd">boolean</span> <span style="color:#61aeee">checkToken</span><span style="color:#999999">(</span>String token<span style="color:#999999">,</span> String account<span style="color:#999999">)</span> <span style="color:#999999">{</span>
<span style="color:#c678dd">try</span> <span style="color:#999999">{</span>
Algorithm algorithm <span style="color:#669900">=</span> Algorithm<span style="color:#999999">.</span><span style="color:#61aeee">HMAC256</span><span style="color:#999999">(</span>account <span style="color:#669900">+</span> encodeSecretKey<span style="color:#999999">)</span><span style="color:#999999">;</span>
JWTVerifier verifier <span style="color:#669900">=</span> JWT<span style="color:#999999">.</span><span style="color:#61aeee">require</span><span style="color:#999999">(</span>algorithm<span style="color:#999999">)</span>
<span style="color:#999999">.</span><span style="color:#61aeee">build</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
DecodedJWT jwt <span style="color:#669900">=</span> verifier<span style="color:#999999">.</span><span style="color:#61aeee">verify</span><span style="color:#999999">(</span>token<span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#c678dd">return</span> <span style="color:#56b6c2">true</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span> <span style="color:#c678dd">catch</span> <span style="color:#999999">(</span>UnsupportedEncodingException e<span style="color:#999999">)</span> <span style="color:#999999">{</span>
<span style="color:#c678dd">return</span> <span style="color:#56b6c2">false</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span>
<span style="color:#999999">}</span>
<span style="color:#5c6370">/**
* 获取用户account
* @param token
* @return
*/</span>
<span style="color:#c678dd">public</span> <span style="color:#c678dd">static</span> String <span style="color:#61aeee">getAccount</span><span style="color:#999999">(</span>String token<span style="color:#999999">)</span><span style="color:#999999">{</span>
<span style="color:#c678dd">try</span> <span style="color:#999999">{</span>
DecodedJWT jwt <span style="color:#669900">=</span> JWT<span style="color:#999999">.</span><span style="color:#61aeee">decode</span><span style="color:#999999">(</span>token<span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#c678dd">return</span> jwt<span style="color:#999999">.</span><span style="color:#61aeee">getClaim</span><span style="color:#999999">(</span><span style="color:#669900">"account"</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#61aeee">asString</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span>
<span style="color:#999999">}</span> <span style="color:#c678dd">catch</span> <span style="color:#999999">(</span>JWTDecodeException e<span style="color:#999999">)</span> <span style="color:#999999">{</span>
<span style="color:#c678dd">return</span> null<span style="color:#999999">;</span>
<span style="color:#999999">}</span>
<span style="color:#999999">}</span>
<span style="color:#999999">}</span>
</code></span></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
<span style="color:rgba(0, 0, 0, 0.75)"><span style="color:#000000"><code class="language-Java">public class JwtInterceptor extends HandlerInterceptorAdapter {
@Autowired
RedisUtil redisUtil;
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
String token = request.getHeader("Authorization");
if (token == null) {
response.setStatus(401);
return false;
}
String account = JwtUtil.getAccount(token);
String redisToken = redisUtil.get(RedisKey.TP_STORE_KEY + account);
boolean isExpire = JwtUtil.checkToken(token, account);
if (redisToken == null || redisToken != token || isExpire) {
response.setStatus(401);
return false;
}
return true;
}
}
</code></span></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
<span style="color:rgba(0, 0, 0, 0.75)"><span style="color:#000000"><code class="language-Java">@Configuration
public class WebConfig implements WebMvcConfigurer {
// 再拦截器中使用了RedisUtil bean类,但是拦截器执行实在spring容器bean初始化之前的
// RedisUtil 将无法注入,为了解决该问题,将JwtInterceptor拦截器先配置为一个bean
// 在注册拦截器时,直接使用配置的bean
@Bean
public JwtInterceptor jwtInterceptor(){
return new JwtInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry){
registry.addInterceptor(jwtInterceptor())
.addPathPatterns("/tp_store/logout");
}
}
</code></span></span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
现在才知道,零基础学习高级Java后,年薪可以这么多!
零基础学IT选Java,易学、高薪、前景广,100万人才缺口,互联网必备人才