Skip to content

Commit 5f213c0

Browse files
committed
todo: qq互联
1 parent 83a959f commit 5f213c0

File tree

7 files changed

+137
-2
lines changed

7 files changed

+137
-2
lines changed

src/Meowv.Blog.Api/appsettings.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,9 @@ authorize:
7070
clientId: '3725213942'
7171
clientSecret: ''
7272
redirectUrl: 'https://admin.meowv.com/oauth/weibo'
73-
scope: 'all'
73+
scope: 'all'
74+
qq:
75+
clientId: '101931838'
76+
clientSecret: ''
77+
redirectUrl: 'https://api.meowv.com/api/meowv/oauth/qq/token'
78+
scope: 'get_user_info'

src/Meowv.Blog.Application/Authorize/Impl/AuthorizeService.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public class AuthorizeService : ServiceBase, IAuthorizeService
3333
private readonly OAuthDingtalkService _dingtalkService;
3434
private readonly OAuthMicrosoftService _microsoftService;
3535
private readonly OAuthWeiboService _weiboService;
36+
private readonly OAuthQQService _qqService;
3637

3738
public AuthorizeService(IOptions<JwtOptions> jwtOption,
3839
IToolService toolService,
@@ -43,7 +44,8 @@ public AuthorizeService(IOptions<JwtOptions> jwtOption,
4344
OAuthAlipayService alipayService,
4445
OAuthDingtalkService dingtalkService,
4546
OAuthMicrosoftService microsoftService,
46-
OAuthWeiboService weiboService)
47+
OAuthWeiboService weiboService,
48+
OAuthQQService qqService)
4749
{
4850
_jwtOption = jwtOption.Value;
4951
_toolService = toolService;
@@ -55,6 +57,7 @@ public AuthorizeService(IOptions<JwtOptions> jwtOption,
5557
_dingtalkService = dingtalkService;
5658
_microsoftService = microsoftService;
5759
_weiboService = weiboService;
60+
_qqService = qqService;
5861
}
5962

6063
/// <summary>
@@ -77,6 +80,7 @@ public async Task<BlogResponse<string>> GetAuthorizeUrlAsync(string type)
7780
"dingtalk" => await _dingtalkService.GetAuthorizeUrl(state),
7881
"microsoft" => await _microsoftService.GetAuthorizeUrl(state),
7982
"weibo" => await _weiboService.GetAuthorizeUrl(state),
83+
"qq" => await _qqService.GetAuthorizeUrl(state),
8084
_ => throw new NotImplementedException($"Not implemented:{type}")
8185
}
8286
};
@@ -113,6 +117,7 @@ public async Task<BlogResponse<string>> GenerateTokenAsync(string type, string c
113117
"dingtalk" => GenerateToken(await _dingtalkService.GetUserByOAuthAsync(type, code, state)),
114118
"microsoft" => GenerateToken(await _microsoftService.GetUserByOAuthAsync(type, code, state)),
115119
"weibo" => GenerateToken(await _weiboService.GetUserByOAuthAsync(type, code, state)),
120+
"qq" => GenerateToken(await _qqService.GetUserByOAuthAsync(type, code, state)),
116121
_ => throw new NotImplementedException($"Not implemented:{type}")
117122
};
118123

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
using Meowv.Blog.Domain.Users;
2+
using Meowv.Blog.Dto.Authorize;
3+
using Meowv.Blog.Extensions;
4+
using Meowv.Blog.Options.Authorize;
5+
using System.Collections.Generic;
6+
using System.Net.Http;
7+
using System.Threading.Tasks;
8+
using System.Web;
9+
10+
namespace Meowv.Blog.Authorize.OAuth.Impl
11+
{
12+
public class OAuthQQService : OAuthServiceBase<QQOptions, AccessTokenBase, QQUserInfo>
13+
{
14+
public override async Task<string> GetAuthorizeUrl(string state)
15+
{
16+
var param = BuildAuthorizeUrlParams(state);
17+
var url = $"{Options.Value.AuthorizeUrl}?{param.ToQueryString()}";
18+
19+
return await Task.FromResult(url);
20+
}
21+
22+
public override async Task<User> GetUserByOAuthAsync(string type, string code, string state)
23+
{
24+
var accessToken = await GetAccessTokenAsync(code, state);
25+
var userInfo = await GetUserInfoAsync(accessToken);
26+
27+
return await UserService.CreateUserAsync(userInfo.Email, type, userInfo.Id, userInfo.Name, userInfo.Avatar, userInfo.Email);
28+
}
29+
30+
public override async Task<AccessTokenBase> GetAccessTokenAsync(string code, string state)
31+
{
32+
var param = BuildAccessTokenParams(code, state);
33+
Options.Value.AccessTokenUrl = $"{Options.Value.AccessTokenUrl}?{param.ToQueryStringWithEncode()}";
34+
35+
using var client = HttpClient.CreateClient();
36+
var response = await client.GetStringAsync(Options.Value.AccessTokenUrl);
37+
38+
var qscoll = HttpUtility.ParseQueryString(response);
39+
40+
return new AccessTokenBase
41+
{
42+
AccessToken = qscoll["access_token"]
43+
};
44+
}
45+
46+
public override async Task<QQUserInfo> GetUserInfoAsync(AccessTokenBase accessToken)
47+
{
48+
using var client = HttpClient.CreateClient();
49+
50+
var openIdResponse = await client.GetStringAsync($"{Options.Value.OpenIdUrl}?access_token={accessToken.AccessToken}");
51+
52+
53+
var response = await client.GetStringAsync(Options.Value.UserInfoUrl);
54+
55+
var userInfo = response.DeserializeToObject<QQUserInfo>();
56+
return userInfo;
57+
}
58+
59+
protected Dictionary<string, string> BuildAuthorizeUrlParams(string state)
60+
{
61+
return new Dictionary<string, string>
62+
{
63+
["client_id"] = Options.Value.ClientId,
64+
["response_type"] = "code",
65+
["redirect_uri"] = Options.Value.RedirectUrl,
66+
["scope"] = Options.Value.Scope,
67+
["state"] = state
68+
};
69+
}
70+
71+
protected Dictionary<string, string> BuildAccessTokenParams(string code, string state)
72+
{
73+
return new Dictionary<string, string>()
74+
{
75+
["client_id"] = Options.Value.ClientId,
76+
["client_secret"] = Options.Value.ClientSecret,
77+
["grant_type"] = "authorization_code",
78+
["redirect_uri"] = Options.Value.RedirectUrl,
79+
["code"] = code,
80+
["state"] = state
81+
};
82+
}
83+
}
84+
}

src/Meowv.Blog.Core/MeowvBlogCoreModule.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ public override void PreConfigureServices(ServiceConfigurationContext context)
116116
var dingtalkOption = authorizeOption.GetSection("dingtalk");
117117
var microsoftOption = authorizeOption.GetSection("microsoft");
118118
var weiboOptions = authorizeOption.GetSection("weibo");
119+
var qqOptions = authorizeOption.GetSection("qq");
119120

120121
Configure<AuthorizeOptions>(authorizeOption);
121122
Configure<GithubOptions>(githubOption);
@@ -124,6 +125,7 @@ public override void PreConfigureServices(ServiceConfigurationContext context)
124125
Configure<DingtalkOptions>(dingtalkOption);
125126
Configure<MicrosoftOptions>(microsoftOption);
126127
Configure<WeiboOptions>(weiboOptions);
128+
Configure<QQOptions>(qqOptions);
127129

128130
options.Github = new GithubOptions
129131
{
@@ -168,6 +170,13 @@ public override void PreConfigureServices(ServiceConfigurationContext context)
168170
RedirectUrl = weiboOptions.GetValue<string>(nameof(options.Weibo.RedirectUrl)),
169171
Scope = weiboOptions.GetValue<string>(nameof(options.Weibo.Scope))
170172
};
173+
options.QQ = new QQOptions
174+
{
175+
ClientId = qqOptions.GetValue<string>(nameof(options.QQ.ClientId)),
176+
ClientSecret = qqOptions.GetValue<string>(nameof(options.QQ.ClientSecret)),
177+
RedirectUrl = qqOptions.GetValue<string>(nameof(options.QQ.RedirectUrl)),
178+
Scope = qqOptions.GetValue<string>(nameof(options.QQ.Scope))
179+
};
171180

172181
authorize = options;
173182
});
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
namespace Meowv.Blog.Options.Authorize
2+
{
3+
public class QQOptions
4+
{
5+
public string ClientId { get; set; }
6+
7+
public string ClientSecret { get; set; }
8+
9+
public string RedirectUrl { get; set; }
10+
11+
public string Scope { get; set; }
12+
13+
public string AuthorizeUrl = "https://graph.qq.com/oauth2.0/authorize";
14+
15+
public string AccessTokenUrl = "https://graph.qq.com/oauth2.0/token";
16+
17+
public string OpenIdUrl = "https://graph.qq.com/oauth2.0/me";
18+
19+
public string UserInfoUrl = "https://graph.qq.com/user/get_user_info";
20+
}
21+
}

src/Meowv.Blog.Core/Options/AuthorizeOptions.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,10 @@ public class AuthorizeOptions
3333
/// Weibo
3434
/// </summary>
3535
public WeiboOptions Weibo { get; set; }
36+
37+
/// <summary>
38+
/// QQ
39+
/// </summary>
40+
public QQOptions QQ { get; set; }
3641
}
3742
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace Meowv.Blog.Dto.Authorize
2+
{
3+
public class QQUserInfo : UserInfoBase
4+
{
5+
}
6+
}

0 commit comments

Comments
 (0)