国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 淺談Java 三種方式實現接口校驗

淺談Java 三種方式實現接口校驗

2021-01-21 13:50BarryW Java教程

這篇文章主要介紹了淺談Java 三種方式實現接口校驗,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

本文介紹了Java 三種方式實現接口校驗,主要包括AOP,MVC攔截器,分享給大家,具體如下:

方法一:AOP

代碼如下定義一個權限注解

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.thinkgem.jeesite.common.annotation;
 
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
/**
 * 權限注解
 * Created by Hamming on 2016/12/
 */
@Target(ElementType.METHOD)//這個注解是應用在方法上
@Retention(RetentionPolicy.RUNTIME)
public @interface AccessToken {
/*  String userId();
  String token();*/
}

獲取頁面請求中的ID token

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Aspect
@Component
public class AccessTokenAspect {
 
  @Autowired
  private ApiService apiService;
 
  @Around("@annotation(com.thinkgem.jeesite.common.annotation.AccessToken)")
  public Object doAccessCheck(ProceedingJoinPoint pjp) throws Throwable{
    HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    String id = request.getParameter("id");
    String token = request.getParameter("token");
    boolean verify = apiService.verifyToken(id,token);
    if(verify){
      Object object = pjp.proceed(); //執行連接點方法
      //獲取執行方法的參數
 
      return object;
    }else {
      return ResultApp.error(3,"token失效");
    }
  }
}

token驗證類  存儲用到redis

?
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package com.thinkgem.jeesite.common.service;
 
import com.thinkgem.jeesite.common.utils.JedisUtils;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.crypto.MacProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import redis.clients.jedis.Jedis;
 
import java.io.*;
import java.security.Key;
import java.util.Date;
 
/**
 *token登陸驗證
 * Created by Hamming on 2016/12/
 */
@Service
public class ApiService {
  private static final String at="accessToken";
 
  public static Key key;
 
//  private Logger logger = LoggerFactorygetLogger(getClass());
  /**
   * 生成token
   * Key以字節流形式存入redis
   *
   * @param date 失效時間
   * @param appId AppId
   * @return
   */
  public String generateToken(Date date, String appId){
    Jedis jedis = null;
    try {
      jedis = JedisUtils.getResource();
      byte[] buf = jedis.get("api:key".getBytes());
      if (buf == null) { // 建新的key
        key = MacProvider.generateKey();
        ByteArrayOutputStream bao = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bao);
        oos.writeObject(key);
        buf = bao.toByteArray();
        jedis.set("api:key".getBytes(), buf);
      } else { // 重用老key
        key = (Key) new ObjectInputStream(new ByteArrayInputStream(buf)).readObject();
      }
 
    }catch (IOException io){
//      System.out.println(io);
    }catch (ClassNotFoundException c){
//      System.out.println(c);
    }catch (Exception e) {
//      logger.error("ApiService", "generateToken", key, e);
    } finally {
      JedisUtils.returnResource(jedis);
    }
 
    String token = Jwts.builder()
        .setSubject(appId)
        .signWith(SignatureAlgorithm.HS512, key)
        .setExpiration(date)
        .compact();
    // 計算失效秒,7889400秒三個月
    Date temp = new Date();
    long interval = (date.getTime() - temp.getTime())/1000;
    JedisUtils.set(at+appId ,token,(int)interval);
    return token;
  }
 
  /**
   * 驗證token
   * @param appId AppId
   * @param token token
   * @return
   */
  public boolean verifyToken(String appId, String token) {
    if( appId == null|| token == null){
      return false;
    }
    Jedis jedis = null;
    try {
      jedis = JedisUtils.getResource();
      if (key == null) {
        byte[] buf = jedis.get("api:key".getBytes());
        if(buf==null){
          return false;
        }
        key = (Key) new ObjectInputStream(new ByteArrayInputStream(buf))readObject();
      }
      Jwts.parser().setSigningKey(key).parseClaimsJws(token).getBody().getSubject().equals(appId);
      return true;
    } catch (Exception e) {
//      logger.error("ApiService", "verifyToken", key, e);
      return false;
    } finally {
      JedisUtils.returnResource(jedis);
    }
  }
 
  /**
   * 獲取token
   * @param appId
   * @return
   */
  public String getToken(String appId) {
    Jedis jedis = null;
    try {
      jedis = JedisUtils.getResource();
      return jedis.get(at+appId);
    } catch (Exception e) {
//      logger.error("ApiService", "getToken", e);
      return "";
    } finally {
      JedisUtils.returnResource(jedis);
    }
  }
}

spring aop配置

?
1
2
3
4
<!--aop -->
<!--   掃描注解bean -->
<context:component-scan base-package="com.thinkgem.jeesite.common.aspect"/>
 <aop:aspectj-autoproxy proxy-target-class="true"/>

驗證權限方法使用 直接用注解就可以了AccessToken

例如

?
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
package com.thinkgem.jeesite.modules.app.web.pay;
 
import com.alibaba.fastjson.JSON;
import com.thinkgem.jeesite.common.annotation.AccessToken;
import com.thinkgem.jeesite.common.base.ResultApp;
import com.thinkgem.jeesite.modules.app.service.pay.AppAlipayConfService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
 
import java.util.HashMap;
import java.util.Map;
 
/**
 * 支付接口
 * Created by Hamming on 2016/12/
 */
@Controller
@RequestMapping(value = "/app/pay")
public class AppPayModule {
 
  @Autowired
  private AppAlipayConfService appAlipayConfService;
 
  @RequestMapping(value = "/alipay", method = RequestMethodPOST, produces="application/json")
  @AccessToken
  @ResponseBody
  public Object alipay(String orderId){
    if(orderId ==null){
      Map re = new HashMap<>();
      re.put("result",3);
      re.put("msg","參數錯誤");
      String json = JSONtoJSONString(re);
      return json;
    }else {
      return null;
    }
  }
}

方法二: AOP方法2

1.定義一個查詢父類,里面包含到authToken跟usedId兩個屬性,所有需要校驗用戶的請求的查詢參數都繼承這個查詢父類,之所以會有這個userId,是因為我們校驗得到用戶之后,需要根據用戶Id獲取一些用戶數據的,所以在AOP層我們就回填了這個參數了,這樣也不會影響之前的代碼邏輯(這個可能跟我的業務需求有關了)

?
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
public class AuthSearchVO {
  
  public String authToken; //校驗字符串
  
  public Integer userId; //APP用戶Id
  
  public final String getAuthToken() {
    return authToken;
  }
 
  public final void setAuthToken(String authToken) {
    this.authToken = authToken;
  }
 
  public final Integer getUserId() {
    return userId;
  }
 
  public final void setUserId(Integer userId) {
    this.userId = userId;
  }
 
  @Override
  public String toString() {
    return "SearchVO [authToken=" + authToken + ", userId=" + userId + "]";
  }
 
}

2.定義一個方法級的注解,所有需要校驗的請求都加上這個注解,用于AOP的攔截(當然你也可以攔截所有控制器的請求)

?
1
2
3
4
5
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthToken {
String type();
}

3.AOP處理,之所以會將注解作為參數傳進來,是因為考慮到可能會有多個APP的校驗,可以利用注解的type屬性加以區分

?
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
public class AuthTokenAOPInterceptor {
 
@Resource
private AppUserService appUserService;
 
private static final String authFieldName = "authToken";
private static final String userIdFieldName = "userId";
 
public void before(JoinPoint joinPoint, AuthToken authToken) throws Throwable{
 
  Object[] args = joinPoint.getArgs(); //獲取攔截方法的參數
  boolean isFound = false;
  for(Object arg : args){
    if(arg != null){
      Class<?> clazz = arg.getClass();//利用反射獲取屬性值
      Field[] fields = clazz.getDeclaredFields();
      int authIndex = -1;
      int userIdIndex = -1;
      for(int i = 0; i < fields.length; i++){
        Field field = fields[i];
        field.setAccessible(true);
        if(authFieldName.equals(field.getName())){//包含校驗Token
          authIndex = i;
        }else if(userIdFieldName.equals(field.getName())){//包含用戶Id
          userIdIndex = i;
        }
      }
 
      if(authIndex >= 0 & userIdIndex >= 0){
        isFound = true;
        authTokenCheck(fields[authIndex], fields[userIdIndex], arg, authToken);//校驗用戶
        break;
      }
    }
  }
  if(!isFound){
    throw new BizException(ErrorMessage.CHECK_AUTHTOKEN_FAIL);
  }
 
}
 
private void authTokenCheck(Field authField, Field userIdField, Object arg, AuthToken authToken) throws Exception{
  if(String.class == authField.getType()){
    String authTokenStr = (String)authField.get(arg);//獲取到校驗Token
    AppUser user = appUserService.getUserByAuthToken(authTokenStr);
    if(user != null){
      userIdField.set(arg, user.getId());
    }else{
      throw new BizException(ErrorMessage.CHECK_AUTHTOKEN_FAIL);
    }
  }
 
}
}

4.最后就是在配置文件中配置這個AOP了(因為我們的spring版本跟aspect版本有點出入,導致用不了基于注解的方式)

?
1
2
3
4
5
6
7
<bean id="authTokenAOPInterceptor" class="com.distinct.app.web.common.auth.AuthTokenAOPInterceptor"/>
<aop:config proxy-target-class="true">
  <aop:pointcut id="authCheckPointcut" expression="@annotation(authToken)"/>
  <aop:aspect ref="authTokenAOPInterceptor" order="1">
    <aop:before method="before" pointcut-ref="authCheckPointcut"/>
  </aop:aspect>
</aop:config>

最后給出測試代碼,這樣的代碼就優雅很多了

?
1
2
3
4
5
6
7
@RequestMapping(value = "/appointments", method = { RequestMethod.GET })
@ResponseBody
@AuthToken(type="disticntApp")
public List<AppointmentVo> getAppointments(AppointmentSearchVo appointmentSearchVo) {
  List<AppointmentVo> appointments = appointmentService.getAppointment(appointmentSearchVo.getUserId(), appointmentSearchVo);
  return appointments;
}

方法三: MVC攔截器

服務器:

拼接token之外所有參數,最后拼接token_key,做MD5,與token參數比對

如果token比對失敗返回狀態碼 500

?
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
public class APIInterceptor extends HandlerInterceptorAdapter {
 
  @Override
  public boolean preHandle(HttpServletRequest request,
      HttpServletResponse response, Object handler) throws Exception {
    Log.info(request);
     
    String token = request.getParameter("token");
     
    // token is not needed when debug
    if(token == null) return true; // !! remember to comment this when deploy on server !!
     
    Enumeration paraKeys = request.getParameterNames();
    String encodeStr = "";
    while (paraKeys.hasMoreElements()) {
      String paraKey = (String) paraKeys.nextElement();
      if(paraKey.equals("token")) 
        break;
      String paraValue = request.getParameter(paraKey);
      encodeStr += paraValue;
    }
    encodeStr += Default.TOKEN_KEY;
    Log.out(encodeStr);
     
    if ( ! token.equals(DigestUtils.md5Hex(encodeStr))) {
      response.setStatus(500);
      return false;
    }
     
    return true;
  }
 
  @Override
  public void postHandle(HttpServletRequest request,
      HttpServletResponse response, Object handler,
      ModelAndView modelAndView) throws Exception {
    Log.info(request);
  }
 
  @Override
  public void afterCompletion(HttpServletRequest request,
      HttpServletResponse response, Object handler, Exception ex)
      throws Exception {
     
  }
}

spring-config.xml配置中加入

?
1
2
3
4
5
6
<mvc:interceptors>
  <mvc:interceptor>
    <mvc:mapping path="/api/*" />
    <bean class="cn.web.interceptor.APIInterceptor" />
  </mvc:interceptor>
</mvc:interceptors>

客戶端:

拼接請求接口的所有參數,最后拼接token_key,做MD5,作為token參數

請求樣例:http://127.0.0.1:8080/interface/api?key0=param0&key1=param1&token=md5(concat(param0, param1))

api測試頁面,用到了Bootstrap和AngularJS,還有一個js的hex_md5函數

?
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
<!doctype html>
<html ng-app>
<head>
  <meta charset="UTF-8">
  <title>API test</title>
  <link href="../css/bootstrap.min.css" rel="external nofollow" rel="stylesheet">
  <script src="../js/md5.min.js"></script>
  <script src="../js/angular.min.js"></script>
  <script>
    function API(url){
      this.url = arguments[0];
      this.params = Array.prototype.slice.call(arguments, 1, arguments.length);
      this.request = function(params){
        var addr = url;
        var values = Array.prototype.slice.call(arguments, 1, arguments.length);
        if(params[0] != undefined && values[0] != undefined && values[0] != '')
          addr += '?' + params[0] + "=" + values[0];
        for(var i=1; i < valueslength; i++)
          if(params[i] != undefined && values[i] != undefined && values[i] != '')
            addr += "&" + params[i] + "=" + values[i];
        return addr;
      }
    }
     
    function APIListCtrl($scope) {
      $scope.md5 = hex_md5;
      $scope.token_key = "9ae5r06fs8";
      $scope.concat = function(){
        var args = Array.prototype.slice.call(arguments, 0, arguments.length);
        args.push($scope.token_key);
        return args.join("");
      }
       
      $scope.apilist = [
       
      new API("account/login", "username", "pwd"),
      new API("account/register", "username", "pwd", "tel", "code"),
       
      ] ;
    }
  </script>
</head>
<body>
 
  <div ng-controller="APIListCtrl">
    <div> Search: <input type="text" ng-model="search"><hr>
    token_key <input type="text" ng-model="token_key">
    md5 <input type="text" ng-model="str"> {{md5(str)}}
    </div>
    <hr>
    <div ng-repeat="api in apilist | filter:search" >
      <form action="{{api.url}}" method="post">
      <a href="{{api.request(api.params, value0, value1, value2, value3, value4, value5, value6, value7, value8, value9)}}" rel="external nofollow" >
      {{api.request(api.params, value0, value1, value2, value3, value4, value5, value6, value7, value8, value9)}}
      </a>
      <br>
      {{concat(value0, value1, value2, value3, value4, value5, value6, value7, value8, value9)}}
      <br>
      {{api.params[0]}} <input id="{{api.params[0]}}" name="{{api.params[0]}}" ng-model="value0" ng-hide="api.params[0]==undefined">
      {{api.params[1]}} <input id="{{api.params[1]}}" name="{{api.params[1]}}" ng-model="value1" ng-hide="api.params[1]==undefined">
      {{api.params[2]}} <input id="{{api.params[2]}}" name="{{api.params[2]}}" ng-model="value2" ng-hide="api.params[2]==undefined">
      {{api.params[3]}} <input id="{{api.params[3]}}" name="{{api.params[3]}}" ng-model="value3" ng-hide="api.params[3]==undefined">
      {{api.params[4]}} <input id="{{api.params[4]}}" name="{{api.params[4]}}" ng-model="value4" ng-hide="api.params[4]==undefined">
      {{api.params[5]}} <input id="{{api.params[5]}}" name="{{api.params[5]}}" ng-model="value5" ng-hide="api.params[5]==undefined">
      {{api.params[6]}} <input id="{{api.params[6]}}" name="{{api.params[6]}}" ng-model="value6" ng-hide="api.params[6]==undefined">
      {{api.params[7]}} <input id="{{api.params[7]}}" name="{{api.params[7]}}" ng-model="value7" ng-hide="api.params[7]==undefined">
      {{api.params[8]}} <input id="{{api.params[8]}}" name="{{api.params[8]}}" ng-model="value8" ng-hide="api.params[8]==undefined">
      {{api.params[9]}} <input id="{{api.params[9]}}" name="{{api.params[9]}}" ng-model="value9" ng-hide="api.params[9]==undefined">
      token <input id="token" name="token" value="{{md5(concat(value0, value1, value2, value3, value4, value5, value6, value7, value8, value9))}}">
      <input type="submit" class="btn" ng-hide="api.params[0]==undefined">
      </form>
      <hr>
    </div>
  </div>
 
</body>
</html>

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:http://www.cnblogs.com/barrywxx/p/6964423.html

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 精品一区二区三区免费 | 欧美精品在线看 | 久久中文字幕一区 | 毛片网站大全 | 国产成人精品一区二区三区福利 | 国产综合一区二区 | 国产欧美精品 | 国产精品久久99 | 亚洲字幕成人中文在线观看 | 国产人体视频 | 黄色三级视频 | 中文字幕网站 | 欧美一区二区三区的 | 久久一区二 | 国产精品福利电影网 | 亚洲欧美一级久久精品 | 亚洲男人网 | 久久一精品 | 亚洲狠狠爱一区二区三区 | 欧美精品一区三区 | 日韩激情一区 | 日韩中文字幕在线 | 九九香蕉视频 | 久久精品国产一区 | 亚洲激情一区二区 | 国产精品久久久久久久久久久久冷 | 精品一区视频 | 午夜黄色影院 | 亚洲天堂久久 | 爱爱视频网址 | 依人在线 | 一区二区三区四区视频 | 色综合久久久 | 精品一区二区三区免费毛片 | 国产精品99 | 欧美激情五月 | 黄色毛片儿 | 欧美亚洲在线 | 小视频免费在线观看 | 视频在线一区 | 亚洲国产成人精品久久 |