关于token失效的处理方法

业务场景

最近公司需要对接一条新的线路,但这线路与之前的线路不一样,我们每次调用API都需要携带token来进行验证,而生成的token也是调用上游的API。如果这样的话就比较简单,我们把token写死就好了,但是这个token有24小时的失效时间,这就需要我们不断的更新token。
⭐注:因为涉及工作内容,以下文档信息以及代码信息皆为虚假信息。

解决方法

⭐解决方法相对来说还是比较简单的,下面说说话我的解决方法,如果各位还有比较好的解决方法的话,欢迎大家评论指正。

  1. 首先我们先调用API获取token,存入Redis缓存,设置过期时间,这就是未失效的token。
  2. 如果缓存中的token过期或者失效,那么我们就重新走第一步,如果没有过期或者失效,那么我们就获取Redis中token。
  3. 携带token请求API。

上游文档解析

JHAPI1
JHAPI2

代码展示

⭐工具类

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
package com.fc.v2.jh;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class JHUtil {
private static String HOST = "XXXXXXXXXXXXXX";
/**
* 拿Token路径
*/
private static String TOKENURL = "XXXXXXXXXXXXX";

private static String CALLURL = "XXXXXXXXXXXXXXX";

private static String APPID = "XXXXXXXXXXXXXXXXXXXXXXX";

private static String APPKEY = "XXXXXXXXXXXXXXXXXX";

public static String getToken(){
JSONObject json = new JSONObject();
json.put("Username", APPID);
json.put("Password", APPKEY);
HttpResponse response = HttpUtil.createPost(HOST + TOKENURL)
.headerMap(head(), true)
.body(String.valueOf(json))
.execute();
JSONObject body = JSONUtil.parseObj(response.body());
String token = (String) body.get("token");
return token;
}

public static HttpResponse CallRequest(String Caller, String Callee,String token){
JSONObject json = new JSONObject();
json.put("Callid", UUID.randomUUID());
json.put("App_id", APPID);
json.put("Caller", Caller);
json.put("Callee", Callee);
json.put("Cdr_url", "XXXXXXXXXXXXXXXXXX");
Map<String,String> map = new HashMap<>();
map.put("Content-Type", "application/json");
map.put("Authorization",token);
HttpResponse result = HttpRequest.post(HOST + CALLURL)
.addHeaders(map)
.body(String.valueOf(json))
.execute();

return result;
}

private static Map<String, String> head() {
//请求头map
Map<String, String> head = new HashMap<>();
head.put("Content-Type", "application/json;charset=utf-8");
return head;
}
}

⭐调用API发起呼叫

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
@PostMapping("/CallRequest")
@RequiresPermissions("gen:LrJHApiController:CallRequest")
@ResponseBody
public AjaxResult CallRequest(String Caller, String Callee){
String token = "";
if (lrAppUserService.selectByTelA(Caller)==null){
return error("该主叫未开户,请联系运营处理");
}
if (redisTemplate.opsForValue().get("token")!=null){
token = "JH " + redisTemplate.opsForValue().get("token").toString();
}else {
String t = JHUtil.getToken();
redisTemplate.opsForValue().set("token",t,60*60*6, TimeUnit.SECONDS);//6小时过期
token = "JH " + t;
System.out.println(t);
}
HttpResponse response = JHUtil.CallRequest(Caller,Callee,token);
JSONObject body = JSONUtil.parseObj(response.body());
if (body.get("taskid").equals("")){
String t = JHUtil.getToken();
redisTemplate.opsForValue().set("token",t,60*60*6, TimeUnit.SECONDS);//6小时过期
token = "JH " + t;
response = JHUtil.CallRequest(Caller,Callee,token);
body = JSONUtil.parseObj(response.body());
System.out.println(t);
}
//String token = (String) body.get("token");

return AjaxResult.successData(200,body);
}

小结

⭐好了,这就是处理这种问题的方法,我总结就是如果有时间限定的一些数据,就用缓存来对它进行处理,而不是将它存到数据库中,因为值经常发生变化,如果我们把它存到数据库中,那么我们每次拿值都要请求一下数据库,这将会对数据库带来不必要的压力,因此选择缓存。以此类推,融会贯通。