.net core 3.1 Identity Server4 (实现GitHub登录) 电脑版发表于:2021/1/19 15:32 ![.netcore](https://img.tnblog.net/arcimg/hb/c857299a86d84ee7b26d181a31e58234.jpg ".netcore") >#.net core 3.1 Identity Server4 (实现GitHub登录) [TOC] 创建GitHub应用 ------------ ![](https://img.tnblog.net/arcimg/hb/1679181068594ff0b40112b3618ee672.png) ![](https://img.tnblog.net/arcimg/hb/dda257fd8bee4ed7b515d3d1f185bcc4.png) ![](https://img.tnblog.net/arcimg/hb/0fd2a20a42d849e58703053fb1f82e97.png) ![](https://img.tnblog.net/arcimg/hb/97423e1dc82942d59fe2c2e033071bb5.png) tn>在下面进行身份授权的时候,我去掉了`Webhook`添加了邮箱的读取。 ![](https://img.tnblog.net/arcimg/hb/0c8f2b40038c4831ad31e1141b1fbea3.png) ![](https://img.tnblog.net/arcimg/hb/a235e4ae492b4788b94f627f644d072a.png) 添加相关代码 ------------ >### 添加相关依赖库 ```bash Install-Package AspNet.Security.OAuth.GitHub -Version 3.1.6 ``` tn>在`Startup`中,添加Github相关扩展 ```csharp services.AddAuthentication() .AddGitHub(options => { options.ClientId = "your_ClientId"; options.ClientSecret = "your_ClientSecret"; // 添加 email options.Scope.Add("user:email"); }); ``` >### 扩展登录相关代码 tn>在`LoginViewModel`实体中,添加扩展登录`ExternalProviders`属性。 ```csharp /// <summary> /// 获取第三方登录扩展 /// </summary> public IEnumerable<AuthenticationScheme> ExternalProviders { get; set; } ``` tn>添加第三方登录注册类`ExternalRegisterViewModel` ```csharp public class ExternalRegisterViewModel { public string Username { get; set; } public string ReturnUrl { get; set; } } ``` tn>在`IdentityCodeAuthController`控制器中修改登录内容 ```csharp [HttpGet] public async Task<IActionResult> Login(string returnUrl) { var vm = new LoginViewModel() { ReturnUrl = returnUrl }; // 获取上下文的内容 var context = await _interaction.GetAuthorizationContextAsync(returnUrl); vm.Username = context?.LoginHint; // 获取第三方登录扩展 var externalProviders = await _signInManager.GetExternalAuthenticationSchemesAsync(); vm.ExternalProviders = externalProviders; return View(vm); } ``` tn>在前台添加显示扩展显示标签。 ```html <!-- 外部登录展示 --> <form asp-controller="IdentityCodeAuth" asp-action="ExternalLogin" asp-route-returnUrl="@Model.ReturnUrl" method="post"> @foreach (var provider in Model.ExternalProviders) { <button name="provider" type="submit" value="@provider.Name">@provider.Name</button> } </form> ``` tn>在添加第三方验证 ```csharp /// <summary> /// 第三方登录扩展处理 /// </summary> /// <param name="returnUrl"></param> /// <returns></returns> public async Task<IActionResult> ExternalLogin(string provider, string returnUrl) { // 制作回调地址 var redirectUri = Url.Action(nameof(ExteranlLoginCallback), "IdentityCodeAuth", new { returnUrl }); var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider,redirectUri); return Challenge(properties, provider); } /// <summary> /// 重定向到外部登录问题 /// </summary> /// <returns></returns> public async Task<IActionResult> ExteranlLoginCallback(string returnUrl) { // 获取外部信息 var info = await _signInManager.GetExternalLoginInfoAsync(); // 当我们获取不到就将它跳转回login页重新登录 if (info == null) { return RedirectToAction("Login"); } // 获取相关信息 var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, false); if (result.Succeeded) { return Redirect(returnUrl); } // 找不到就注册 var username = info.Principal.FindFirst(ClaimTypes.Name.Replace(" ", "_")).Value; return View("ExternalRegister",new ExternalRegisterViewModel { Username = username, ReturnUrl = returnUrl }); } /// <summary> /// 获取第三方注册处理 /// </summary> /// <returns></returns> public async Task<IActionResult> ExternalRegister(ExternalRegisterViewModel vm) { // 获取外部信息 var info = await _signInManager.GetExternalLoginInfoAsync(); // 当我们获取不到就将它跳转回login页重新登录 if (info == null) { return RedirectToAction("Login"); } // 创建用户 (这里就没要密码) var user = new IdentityUser(vm.Username); // 获取邮箱 user.Email = info.Principal.Claims.FirstOrDefault(x => x.Type.Contains("email"))?.Value; var result = await _userManager.CreateAsync(user); if (!result.Succeeded) { return View(vm); } // 向指定用户添加外部用户登录信息 result = await _userManager.AddLoginAsync(user, info); if (!result.Succeeded) { return View(vm); } // 用户登录 await _signInManager.SignInAsync(user,false); return Redirect(vm.ReturnUrl); } ``` tn>添加注册页面`ExternalRegister` ```csharp @model ExternalRegisterViewModel <form asp-controller="IdentityCodeAuth" asp-action="ExternalRegister" method="post"> <input type="hidden" asp-for="ReturnUrl" /> <div> <label>Username</label> <input asp-for="Username" /> <span asp-validation-for="Username"></span> </div> <div> <button type="submit">Register In</button> </div> </form> ``` 运行测试 ------------ ![](https://img.tnblog.net/arcimg/hb/7d02c4d3b1ed47a59a07800bd560b461.png) ![](https://img.tnblog.net/arcimg/hb/f2b4cef5e0304a21940cdde8c94f8429.png) ![](https://img.tnblog.net/arcimg/hb/2aa91b6250534364a5e5b3b4ea0b23f2.png) ![](https://img.tnblog.net/arcimg/hb/417f0a97f0ba475ba854b045d521e2ff.png) tn>我们发现邮箱仍然没有出来,接着我们只需要添加邮箱相关资源即可。 ![](https://img.tnblog.net/arcimg/hb/f08c2e459b1d4f40807eb282f350fbf7.png) ![](https://img.tnblog.net/arcimg/hb/3b056382ce1e4f2ba1dbf3434110c604.png) ![](https://img.tnblog.net/arcimg/hb/bc5554c5e10f41fc98810cd30d0204e6.png) tn>然后再运行一次 ![](https://img.tnblog.net/arcimg/hb/722fb24c92ea4288b619d4d9dc8d21db.png)