Springboot 實現api校驗和登入驗證
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萬人才缺口,網際網路必備人才