官方文档:https://developer.github.com/v3/oauth/#1-redirect-users-to-request-github-access语言不分国界,cnodejs 就用 github 了登陆啊
[Route("/oauth/[controller]")]
public class GithubController : HomeBaseController
{
[HttpGet]
public IActionResult Step1([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 Callback([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"]);
// https 请求
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;
/*
上面这行代码出错
{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()}
*/
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}");
}
}
```