/// <summary> /// code -> oauth.access_token + openid /// </summary> /// <param name="code">用于换取网页授权access_token。此code只能使用一次,5分钟未被使用自动过期。</param> /// <param name="redirectUri"></param> /// <returns></returns> protected virtual async Task <WeixinOAuthTokenResponse> CustomExchangeCodeAsync(string code, string redirectUri) { var query = new QueryBuilder() { { "appid", Options.AppId }, { "secret", Options.AppSecret }, { "code", code }, { "grant_type", "authorization_code" }, { "redirect_uri", redirectUri } }; var url = Options.TokenEndpoint + query; Logger.LogInformation($"Exchanging code via {url}..."); var response = await Backchannel.GetAsync(url, Context.RequestAborted); if (!response.IsSuccessStatusCode) { var error = "An error occured while exchanging the code."; Logger.LogError($"{error} The remote server returned a {response.StatusCode} response with the following payload: {response.Headers.ToString()} {await response.Content.ReadAsStringAsync()}"); //throw new HttpRequestException($"{error}"); return(WeixinOAuthTokenResponse.Failed(new Exception(error))); } var payload = JObject.Parse(await response.Content.ReadAsStringAsync()); var result = WeixinOAuthTokenResponse.Success(payload); //错误时微信会返回错误JSON数据包,示例如下: { "errcode":40029,"errmsg":"invalid code"} if (string.IsNullOrWhiteSpace(result.AccessToken)) { int errorCode = WeixinOAuthHandlerHelper.GetErrorCode(payload); var errorMessage = WeixinOAuthHandlerHelper.GetErrorMessage(payload); return(WeixinOAuthTokenResponse.Failed(new Exception($"The remote server returned an error while exchanging the code. {errorCode} {errorMessage}"))); } return(result); }
private async Task <ClaimsIdentity> RetrieveUserInfoAsync(string accessToken, string openId, ClaimsIdentity identity) { //call userinfo var query = new QueryBuilder(); query.Add("access_token", accessToken); query.Add("openid", openId); query.Add("lang", Options.LanguageCode); var url = Options.UserInformationEndpoint + query; Logger.LogInformation($"Retrieving user info via {url}..."); var response = await Backchannel.GetAsync(url, Context.RequestAborted); if (!response.IsSuccessStatusCode) { Logger.LogError($"An error occurred while retrieving the user profile: the remote server returned a {response.StatusCode} response with the following payload: {response.Headers.ToString()} {await response.Content.ReadAsStringAsync()}"); throw new HttpRequestException("An error occured while retrieving the user profile."); } var payload = JObject.Parse(await response.Content.ReadAsStringAsync()); int errorCode = WeixinOAuthHandlerHelper.GetErrorCode(payload); if (errorCode != 0) { var errorMessage = WeixinOAuthHandlerHelper.GetErrorMessage(payload); Logger.LogError($"The remote server returned an error while retrieving the user profile. {errorCode} {errorMessage}"); throw new Exception($"The remote server returned an error while retrieving the user profile. {errorCode} {errorMessage}"); } else { //提取userinfo // std:Name var nickname = WeixinOAuthHandlerHelper.GetNickName(payload); identity.AddOptionalClaim(ClaimTypes.Name, nickname, this.Options.ClaimsIssuer); identity.AddOptionalClaim(WeixinOAuthClaimTypes.NickName, nickname, Options.ClaimsIssuer); var sex = WeixinOAuthHandlerHelper.GetGender(payload); identity.AddOptionalClaim(WeixinOAuthClaimTypes.Gender, sex, Options.ClaimsIssuer); var province = WeixinOAuthHandlerHelper.GetProvince(payload); identity.AddOptionalClaim(WeixinOAuthClaimTypes.Province, province, Options.ClaimsIssuer); var city = WeixinOAuthHandlerHelper.GetCity(payload); identity.AddOptionalClaim(WeixinOAuthClaimTypes.City, city, Options.ClaimsIssuer); var country = WeixinOAuthHandlerHelper.GetCountry(payload); identity.AddOptionalClaim(WeixinOAuthClaimTypes.Country, country, Options.ClaimsIssuer); var headImageUrl = WeixinOAuthHandlerHelper.GetHeadImageUrl(payload); identity.AddOptionalClaim(WeixinOAuthClaimTypes.HeadImageUrl, headImageUrl, Options.ClaimsIssuer); var privileges = WeixinOAuthHandlerHelper.GetPrivileges(payload); foreach (string privilege in privileges) { identity.AddOptionalClaim(WeixinOAuthClaimTypes.Privilege, privilege, Options.ClaimsIssuer); } var unionId = WeixinOAuthHandlerHelper.GetUnionId(payload); identity.AddOptionalClaim(WeixinOAuthClaimTypes.UnionId, unionId, Options.ClaimsIssuer); } return(identity); }