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 . Name , 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 . ToQueryString ( ) } ";
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 } &fmt=json") ;
51+ var openId = openIdResponse . DeserializeToObject < QQOpenId > ( ) . OpenId ;
52+
53+ var param = BuildUserInfoParams ( accessToken . AccessToken , openId ) ;
54+ Options . Value . UserInfoUrl = $ "{ Options . Value . UserInfoUrl } ?{ param . ToQueryString ( ) } ";
55+
56+ var response = await client . GetStringAsync ( Options . Value . UserInfoUrl ) ;
57+
58+ var userInfo = response . DeserializeToObject < QQUserInfo > ( ) ;
59+ userInfo . Id = openId ;
60+
61+ return userInfo ;
62+ }
63+
64+ protected Dictionary < string , string > BuildAuthorizeUrlParams ( string state )
65+ {
66+ return new Dictionary < string , string >
67+ {
68+ [ "client_id" ] = Options . Value . ClientId ,
69+ [ "response_type" ] = "code" ,
70+ [ "redirect_uri" ] = Options . Value . RedirectUrl ,
71+ [ "scope" ] = Options . Value . Scope ,
72+ [ "state" ] = state
73+ } ;
74+ }
75+
76+ protected Dictionary < string , string > BuildAccessTokenParams ( string code , string state )
77+ {
78+ return new Dictionary < string , string > ( )
79+ {
80+ [ "client_id" ] = Options . Value . ClientId ,
81+ [ "client_secret" ] = Options . Value . ClientSecret ,
82+ [ "grant_type" ] = "authorization_code" ,
83+ [ "redirect_uri" ] = Options . Value . RedirectUrl ,
84+ [ "code" ] = code ,
85+ [ "state" ] = state
86+ } ;
87+ }
88+
89+ protected Dictionary < string , string > BuildUserInfoParams ( string accessToken , string openId )
90+ {
91+ return new Dictionary < string , string > ( )
92+ {
93+ [ "access_token" ] = accessToken ,
94+ [ "oauth_consumer_key" ] = Options . Value . ClientId ,
95+ [ "openid" ] = openId ,
96+ } ;
97+ }
98+ }
99+ }
0 commit comments