这段使用github登陆的代码有问题吗

kellynic 2016-11-01 10:16:36
官方文档:https://developer.github.com/v3/oauth/#1-redirect-users-to-request-github-access

	[Route("/oauth/[controller]")]
public class GithubController : HomeBaseController
{
[HttpGet]
public IActionResult 首页([FromServices] IConfigurationRoot cfg) {
string state = Guid.NewGuid().ToString();
Session.SetString("github_state", state);
var client_id = WebUtility.UrlEncode(cfg["oauth:github:client_id"]);
var redirect_uri = WebUtility.UrlEncode(cfg["oauth:github:redirect_uri"]);
return Redirect($"https://github.com/login/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}&state={state}&allow_signup=false");
}
[HttpGet("callback")]
public IActionResult 回调([FromServices] IConfigurationRoot cfg, [FromQuery] string code,
[FromQuery] string error, [FromQuery] string error_description, [FromQuery] string error_uri, [FromQuery] string state) {
if (state != Session.GetString("github_state")) throw new Exception("state 值与 session 不一致");
var client_id = WebUtility.UrlEncode(cfg["oauth:github:client_id"]);
var client_secret = WebUtility.UrlEncode(cfg["oauth:github:client_secret"]);
var redirect_uri = WebUtility.UrlEncode(cfg["oauth:github:redirect_uri"]);
HttpClientHandler clientHandler = new HttpClientHandler { ClientCertificateOptions = ClientCertificateOption.Automatic };
clientHandler.ServerCertificateCustomValidationCallback = (a, b, c, d) => true;
HttpClient client = new HttpClient(clientHandler);
StringContent content = new StringContent($"client_id={client_id}&client_secret={client_secret}&code={code}&redirect_uri={redirect_uri}&state={state}");
var res = client.PostAsync("https://github.com/login/oauth/access_token", content).Result;
// 上面这行代码出错,详细见后面说明

string rt = res.Content.ReadAsStringAsync().Result;
//access_token=e72e16c7e42f292c6912e7710c838347ae178b4a&scope=user%2Cgist&token_type=bearer
Dictionary<string, string> rtnv = new Dictionary<string, string>();
foreach(string tmp1 in rt.Replace("&", "&").Split('&')) {
string[] tmp2 = tmp1.Split(new char[] { '=' }, 2);
if (tmp2.Length != 2) continue;
string k = WebUtility.UrlDecode(tmp2[0].Trim());
string v = WebUtility.UrlDecode(tmp2[1].Trim());
if (rtnv.ContainsKey(k)) rtnv[k] = v;
else rtnv.Add(k, v);
}
string access_token;
rtnv.TryGetValue("access_token", out access_token);

return Redirect($"https://api.github.com/user?access_token?{access_token}");
}
bool serverCertificateCustomValidationCallback(HttpRequestMessage sender, X509Certificate2 certificate, X509Chain chain, SslPolicyErrors errors) {
return true;
}
}


var res = client.PostAsync("https://github.com/login/oauth/access_token", content).Result; 这行代码出错
{System.Net.Http.WinHttpException: 服务器返回的信息无效或不可识别
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at System.Net.Http.WinHttpHandler.<StartRequest>d__101.MoveNext()}

本地开发环境地址:http://localhost:8888
...全文
184 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
kellynic 2016-11-01
  • 打赏
  • 举报
回复
引用 2 楼 Chinajiyong 的回复:
或者这种

HttpContent content = new StringContent(@"{ ""client_id"": ""XXX""}");


{
"client_id" : "9cb284c7f59**248d0c2",
"client_secret" : "b9bf39e345*75998b38714f23****bf86ac98fdb2",
"code" : "854ce37f96***7cdeca8",
"redirect_uri" : "http://localhost:8888/oauth/github/callback",
"state" : "1e1ddda1-247e-4e9b-b642-adc0613f0a18"
}

标 * 的为不想公布的参数,提交内容改成 json 方式,您看是否正常?



还是这里报错

An unhandled exception occurred while processing the request.
WinHttpException: 服务器返回的信息无效或不可识别
EnForGrass 2016-11-01
  • 打赏
  • 举报
回复
或者这种

HttpContent content = new StringContent(@"{ ""client_id"": ""XXX""}"); 
EnForGrass 2016-11-01
  • 打赏
  • 举报
回复
请先保证 client_id,client_secret这些参数正确, StringContent content = new StringContent($"client_id={client_id}&client_secret={client_secret}&code={code}&redirect_uri={redirect_uri}&state={state}"); 我一般习惯这样写

List<KeyValuePair<String, String>> paramList = new List<KeyValuePair<String, String>>();
                paramList.Add(new KeyValuePair<string, string>("client_id", "XXX"));

                response = httpClient.PostAsync(new Uri(url), new FormUrlEncodedContent(paramList)).Result;
kellynic 2016-11-01
  • 打赏
  • 举报
回复
引用 4 楼 Chinajiyong 的回复:
没看出问题呢,你可以按如下步骤检查一遍
 1.假如需要传递的两个参数是startId ,itemcount,传递的格式是Json。代码如下:
var requestJson = JsonConvert.SerializeObject(new { client_id= "9cb284c7f59**248d0c2", client_secret= "b9bf39e345*75998b38714f23****bf86ac98fdb2" });
  代码的运行结果:{"client_id":"9cb284c7f59**248d0c2","client_secret":"b9bf39e345*75998b38714f23****bf86ac98fdb2"}

  然后用System.Net.Http.StringContent把它打个包:

HttpContent httpContent = new StringContent(requestJson);

  然后设置一下ContentType:


httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");

2. 通过Http Post调用得到返回结果



var httpClient = new HttpClient();
var responseJson = httpClient.PostAsync("http://localhost:9000/api/demo/sitelist", httpContent)
.Result.Content.ReadAsStringAsync().Result;


多谢大神的耐心解答,请看结果

EnForGrass 2016-11-01
  • 打赏
  • 举报
回复
没看出问题呢,你可以按如下步骤检查一遍  1.假如需要传递的两个参数是startId ,itemcount,传递的格式是Json。代码如下: var requestJson = JsonConvert.SerializeObject(new { client_id= "9cb284c7f59**248d0c2", client_secret= "b9bf39e345*75998b38714f23****bf86ac98fdb2" });   代码的运行结果:{"client_id":"9cb284c7f59**248d0c2","client_secret":"b9bf39e345*75998b38714f23****bf86ac98fdb2"}   然后用System.Net.Http.StringContent把它打个包:

HttpContent httpContent = new StringContent(requestJson);
  然后设置一下ContentType:


httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
2. 通过Http Post调用得到返回结果


var httpClient = new HttpClient();
var responseJson = httpClient.PostAsync("http://localhost:9000/api/demo/sitelist", httpContent)
    .Result.Content.ReadAsStringAsync().Result;

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧