Skip to content

Commit 2c6e07e

Browse files
committed
重构AuthTokenFilter
1 parent 41c8c07 commit 2c6e07e

7 files changed

+87
-106
lines changed
+19-93
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
using System;
2-
using System.Net.Http.Headers;
3-
using System.Threading;
1+
using System.Net.Http.Headers;
42
using System.Threading.Tasks;
53
using WebApiClient.Contexts;
64

@@ -9,71 +7,18 @@ namespace WebApiClient.AuthTokens
97
/// <summary>
108
/// 表示OAuth授权的token过滤器抽象类
119
/// </summary>
12-
public abstract class AuthTokenFilter : IApiActionFilter, IDisposable
10+
public abstract class AuthTokenFilter : IApiActionFilter
1311
{
1412
/// <summary>
1513
/// 最近请求到的token
1614
/// </summary>
17-
private TokenResult tokenResult;
18-
19-
/// <summary>
20-
/// token相关异常
21-
/// </summary>
22-
private Exception tokenException;
23-
24-
/// <summary>
25-
/// 计时器
26-
/// </summary>
27-
private readonly Timer tokenTimer;
15+
private TokenResult token;
2816

2917
/// <summary>
3018
/// 异步锁
3119
/// </summary>
3220
private readonly AsyncRoot asyncRoot = new AsyncRoot();
3321

34-
/// <summary>
35-
/// OAuth授权的token过滤器抽象类
36-
/// </summary>
37-
public AuthTokenFilter()
38-
{
39-
this.tokenTimer = new Timer(async (state) =>
40-
{
41-
using (await this.asyncRoot.LockAsync())
42-
{
43-
await this.RefreshTokenAsync();
44-
}
45-
46-
if (this.tokenException == null)
47-
{
48-
var dueTime = this.GetDueTimeSpan(this.tokenResult.ExpiresIn);
49-
this.tokenTimer.Change(dueTime, Timeout.InfiniteTimeSpan);
50-
}
51-
}, null, Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);
52-
}
53-
54-
/// <summary>
55-
/// 刷新token
56-
/// </summary>
57-
/// <returns></returns>
58-
private async Task RefreshTokenAsync()
59-
{
60-
try
61-
{
62-
if (string.IsNullOrEmpty(this.tokenResult.RefreshToken) == true)
63-
{
64-
this.tokenResult = await this.RequestTokenResultAsync();
65-
}
66-
else
67-
{
68-
this.tokenResult = await this.RequestRefreshTokenAsync(this.tokenResult.RefreshToken);
69-
}
70-
}
71-
catch (Exception ex)
72-
{
73-
this.tokenException = ex;
74-
}
75-
}
76-
7722
/// <summary>
7823
/// 请求完成之后
7924
/// </summary>
@@ -93,45 +38,34 @@ async Task IApiActionFilter.OnBeginRequestAsync(ApiActionContext context)
9338
{
9439
using (await this.asyncRoot.LockAsync())
9540
{
96-
await this.InitTokenIfNullTokenAsync();
41+
await this.InitOrRefreshTokenAsync();
9742
}
9843

99-
if (this.tokenException != null)
100-
{
101-
throw this.tokenException;
102-
}
103-
this.AccessTokenResult(context, this.tokenResult);
44+
this.AccessTokenResult(context, this.token);
10445
}
10546

10647
/// <summary>
107-
/// 初始化Token
48+
/// 初始化或刷新token
10849
/// </summary>
10950
/// <returns></returns>
110-
private async Task InitTokenIfNullTokenAsync()
51+
private async Task InitOrRefreshTokenAsync()
11152
{
112-
try
53+
if (this.token == null)
11354
{
114-
if (this.tokenResult == null)
115-
{
116-
this.tokenResult = await this.RequestTokenResultAsync();
117-
var dueTime = this.GetDueTimeSpan(this.tokenResult.ExpiresIn);
118-
this.tokenTimer.Change(dueTime, Timeout.InfiniteTimeSpan);
119-
}
55+
this.token = await this.RequestTokenResultAsync();
12056
}
121-
catch (Exception ex)
57+
else if (this.token.IsExpired() == true)
12258
{
123-
this.tokenException = ex;
59+
if (this.token.CanRefresh() == true)
60+
{
61+
this.token = await this.RequestRefreshTokenAsync(this.token.RefreshToken);
62+
}
63+
else
64+
{
65+
this.token = await this.RequestTokenResultAsync();
66+
}
12467
}
125-
}
126-
127-
/// <summary>
128-
/// 返回Timer延时时间
129-
/// </summary>
130-
/// <param name="expiresIn"></param>
131-
/// <returns></returns>
132-
private TimeSpan GetDueTimeSpan(long expiresIn)
133-
{
134-
return TimeSpan.FromSeconds((double)expiresIn * 0.9d);
68+
this.token.EnsureSuccess();
13569
}
13670

13771
/// <summary>
@@ -159,13 +93,5 @@ protected virtual void AccessTokenResult(ApiActionContext context, TokenResult t
15993
/// <param name="refresh_token">获取token时返回的refresh_token</param>
16094
/// <returns></returns>
16195
protected abstract Task<TokenResult> RequestRefreshTokenAsync(string refresh_token);
162-
163-
/// <summary>
164-
/// 释放资源
165-
/// </summary>
166-
public void Dispose()
167-
{
168-
this.tokenTimer.Dispose();
169-
}
17096
}
17197
}

WebApiClient/AuthTokens/TokenResult.cs

+41-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using WebApiClient.DataAnnotations;
1+
using System;
2+
using System.Net.Http;
3+
using WebApiClient.DataAnnotations;
24

35
namespace WebApiClient.AuthTokens
46
{
@@ -7,6 +9,11 @@ namespace WebApiClient.AuthTokens
79
/// </summary>
810
public class TokenResult
911
{
12+
/// <summary>
13+
/// token创建时间
14+
/// </summary>
15+
private readonly DateTime createTime = DateTime.Now;
16+
1017
/// <summary>
1118
/// access_token
1219
/// </summary>
@@ -44,12 +51,44 @@ public class TokenResult
4451
[AliasAs("error")]
4552
public string Error { get; set; }
4653

54+
/// <summary>
55+
/// 确保token成功
56+
/// </summary>
57+
/// <exception cref="HttpRequestException"></exception>
58+
public TokenResult EnsureSuccess()
59+
{
60+
if (this.IsSuccess() == true)
61+
{
62+
return this;
63+
}
64+
throw new HttpRequestException(this.Error);
65+
}
66+
4767
/// <summary>
4868
/// 返回是否成功
4969
/// </summary>
70+
/// <returns></returns>
5071
public bool IsSuccess()
5172
{
52-
return string.IsNullOrEmpty(Error);
73+
return string.IsNullOrEmpty(this.Error);
74+
}
75+
76+
/// <summary>
77+
/// 返回是否已过期
78+
/// </summary>
79+
/// <returns></returns>
80+
public bool IsExpired()
81+
{
82+
return DateTime.Now.Subtract(this.createTime) > TimeSpan.FromSeconds(this.ExpiresIn);
83+
}
84+
85+
/// <summary>
86+
/// 返回token是否支持刷新
87+
/// </summary>
88+
/// <returns></returns>
89+
public bool CanRefresh()
90+
{
91+
return string.IsNullOrEmpty(this.RefreshToken) == false;
5392
}
5493
}
5594
}

WebApiClient/GlobalFilterCollection.cs

-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using System.Collections;
33
using System.Collections.Generic;
4-
using WebApiClient;
54

65
namespace WebApiClient
76
{

WebApiClient/HttpApiClient.Static.cs

+27-8
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,16 @@ namespace WebApiClient
1010
public partial class HttpApiClient
1111
{
1212
/// <summary>
13-
/// 使用SocketsHttpHandler开关项的名称
13+
/// 一个站点内的默认连接数限制
1414
/// </summary>
15-
private const string useSocketsHttpHandlerSwitch = "System.Net.Http.UseSocketsHttpHandler";
15+
private static int connectionLimit = 128;
1616

17+
#if NETCOREAPP2_1
1718
/// <summary>
18-
/// 获取或设置一个站点内的默认连接数限制
19-
/// 这个值在初始化HttpClientHandler时使用
20-
/// 默认值为128
19+
/// 使用SocketsHttpHandler开关项的名称
2120
/// </summary>
22-
/// <exception cref="ArgumentOutOfRangeException"></exception>
23-
public static int ConnectionLimit { get; set; } = 128;
21+
private const string useSocketsHttpHandlerSwitch = "System.Net.Http.UseSocketsHttpHandler";
2422

25-
#if NETCOREAPP2_1
2623
/// <summary>
2724
/// 获取或设置HttpClientHandler是否包装和使用SocketsHttpHandler
2825
/// </summary>
@@ -39,6 +36,28 @@ public static bool UseSocketsHttpHandler
3936
}
4037
#endif
4138

39+
/// <summary>
40+
/// 获取或设置一个站点内的默认连接数限制
41+
/// 这个值在初始化HttpClientHandler时使用
42+
/// 默认值为128
43+
/// </summary>
44+
/// <exception cref="ArgumentOutOfRangeException"></exception>
45+
public static int ConnectionLimit
46+
{
47+
get
48+
{
49+
return connectionLimit;
50+
}
51+
set
52+
{
53+
if (value <= 0)
54+
{
55+
throw new ArgumentOutOfRangeException();
56+
}
57+
connectionLimit = value;
58+
}
59+
}
60+
4261
/// <summary>
4362
/// 创建实现了指定接口的HttpApiClient实例
4463
/// </summary>

WebApiClient/HttpProxy.cs

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.Linq;
43
using System.Net;
54
using System.Text;
65

WebApiClient/ProxyValidator.cs

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.Net;
43
using System.Net.Sockets;
54
using System.Text;

WebApiClient/WebApiClient.csproj

0 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)