使用SPA+.NET Core3.1實現 GitHub第三方受權登陸 相似使用AspNet.Security.OAuth.GitHub,前端使用以下:VUE+Vue-Router+axioshtml
什麼配置的過程不說了。。有一推。前端
下面爲示例node
client_id:0be6b05fc717bfc4fb67 client_secret:dcaced9f176afba64e89d88b9b06ffc4a887a609
Getios
https://github.com/login/oauth/authorize?client_id=0be6b05fc717bfc4fb67&redirect_uri=https://localhost:5001/signin-github
會重定向到git
https://localhost:5001/signin-github?code=07537a84d12bbae08361github
這個code放到下面的請求中,獲取access_token
POST方式(PostMan去請求)json
https://github.com/login/oauth/access_token?client_id=0be6b05fc717bfc4fb67&client_secret=dcaced9f176afba64e89d88b9b06ffc4a887a609&code=07537a84d12bbae08361
Get方式axios
https://api.github.com/user?access_token=787506afa3271d077b98f18af56d7cfdc8db43b4
而後就能獲取用戶信息後端
{ "login": "luoyunchong", "id": 18613266, "node_id": "MDQ6VXNlcjE4NjEzMjY2", "avatar_url": "https://avatars1.githubusercontent.com/u/18613266?v=4", "gravatar_id": "", "url": "https://api.github.com/users/luoyunchong", "html_url": "https://github.com/luoyunchong", "followers_url": "https://api.github.com/users/luoyunchong/followers", "following_url": "https://api.github.com/users/luoyunchong/following{/other_user}", "gists_url": "https://api.github.com/users/luoyunchong/gists{/gist_id}", "starred_url": "https://api.github.com/users/luoyunchong/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/luoyunchong/subscriptions", "organizations_url": "https://api.github.com/users/luoyunchong/orgs", "repos_url": "https://api.github.com/users/luoyunchong/repos", "events_url": "https://api.github.com/users/luoyunchong/events{/privacy}", "received_events_url": "https://api.github.com/users/luoyunchong/received_events", "type": "User", "site_admin": false, "name": "IGeekFan", "company": null, "blog": "https://blog.igeekfan.cn", "location": null, "email": "luoyunchong@foxmail.com", "hireable": null, "bio": "學習之路漫漫無期。", "public_repos": 14, "public_gists": 0, "followers": 16, "following": 11, "created_at": "2016-04-22T10:33:44Z", "updated_at": "2019-12-21T14:49:33Z" }
如下代碼爲主要代碼,完整代碼看下面的DEMO連接。api
使用WebApi時,看了一些項目,全是基於MVC結構的,都不是我想要的。看了一些博客上面介紹 ,步驟都是千篇一概,都是配合先後端分離的。
後端運行在:https://localhost:5001
本地測試時,gitHub回調地址設置 http(s)://ip:端口/signin-github
前端請求https://localhost:5001/signin?provider=GitHub&redirectUrl=http://localhost:8080/login-result
google-登陸,微軟文檔,其中有一個更改默認回調 URI,經過 AddGitHub中的CallbackPath屬性配置。
介紹了回調地址應配置signin-google,因此這裏應該是signin-github,他是能夠配置的,不須要本身寫程序處理signin-google這個路由,內部有中間件已經處理了。
具體上面的根據code獲取access_token,根據access_token獲取用戶的信息的過程,這些處理的過程,都不須要咱們本身處理。咱們能夠用直接獲取用戶信息。
一個方法SignIn,只要return Challenge(properties, provider);,
這個url爲另外一個獲取用戶信息的路由,只要拼接好地址便可。
var authenticateResult = await _contextAccessor.HttpContext.AuthenticateAsync(provider); string email = authenticateResult.Principal.FindFirst(ClaimTypes.Email)?.Value; string name = authenticateResult.Principal.FindFirst(ClaimTypes.Name)?.Value;
須要注入
private readonly IHttpContextAccessor _contextAccessor; public AuthenticationController( IHttpContextAccessor contextAccessor) { _contextAccessor = contextAccessor; }
打開NuGet包管理,安裝包
Install-Package AspNet.Security.OAuth.GitHub
appSettings.json
"Authentication": { "GitHub": { "ClientId": "0be6b05fc717bfc4fb67", "ClientSecret": "dcaced9f176afba64e89d88b9b06ffc4a887a609" } }
add擴展方法
public static class JwtConfiguration { public static void AddJwtConfiguration(this IServiceCollection services, IConfiguration configuration) { services.AddAuthentication(opts => { opts.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; opts.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; }).AddCookie(options => { options.LoginPath = "/signin"; options.LogoutPath = "/signout"; }).AddGitHub(options => { options.ClientId = configuration["Authentication:GitHub:ClientId"]; options.ClientSecret = configuration["Authentication:GitHub:ClientSecret"]; }); } }
默認狀況下,如頭像,email,是沒有獲取的。
.AddGitHub(options => { options.ClientId = configuration["Authentication:GitHub:ClientId"]; options.ClientSecret = configuration["Authentication:GitHub:ClientSecret"]; //options.CallbackPath = new PathString("~/signin-github");//與GitHub上的回調地址相同,默認便是/signin-github options.Scope.Add("user:email"); //authenticateResult.Principal.FindFirst(LinConsts.Claims.AvatarUrl)?.Value; 獲得GitHub頭像 options.ClaimActions.MapJsonKey(LinConsts.Claims.AvatarUrl, "avatar_url"); options.ClaimActions.MapJsonKey(LinConsts.Claims.BIO, "bio"); options.ClaimActions.MapJsonKey(LinConsts.Claims.BlogAddress, "blog"); }); #其中LinConsts類爲靜態常量 public static class LinConsts { public static class Claims { public const string BIO = "urn:github:bio"; public const string AvatarUrl = "urn:github:avatar_url"; public const string BlogAddress = "urn:github:blog"; } }
startup.cs
ConfigureServices中配置此服務
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); services.AddJwtConfiguration(Configuration);
建立AuthenticationController.cs
增長SignIn,用於處理用戶受權成功後,重定回signin-callback,並將參數帶回。
private readonly IHttpContextAccessor _contextAccessor; private readonly IConfiguration _configuration; public AuthenticationController(IHttpContextAccessor contextAccessor, IConfiguration configuration) { _contextAccessor = contextAccessor; _configuration = configuration; } [HttpGet("~/signin")] public async Task<IActionResult> SignIn(string provider, string redirectUrl) { var request = _contextAccessor.HttpContext.Request; var url = $"{request.Scheme}://{request.Host}{request.PathBase}{request.Path}-callback?provider={provider}&redirectUrl={redirectUrl}"; var properties = new AuthenticationProperties { RedirectUri = url }; properties.Items["LoginProviderKey"] = provider; return Challenge(properties, provider); }
在signin方法中,用戶點擊受權後(第一次),會根據其傳遞的URL,重定向到這個地址,signin-callback,參數也會一同攜帶。provider爲GitHub,redirectUrl爲:http://localhost:8081/login-result.
[HttpGet("~/signin-callback")] public async Task<IActionResult> Home(string provider = null, string redirectUrl = "") { var authenticateResult = await _contextAccessor.HttpContext.AuthenticateAsync(provider); if (!authenticateResult.Succeeded) return Redirect(redirectUrl); var openIdClaim = authenticateResult.Principal.FindFirst(ClaimTypes.NameIdentifier); if (openIdClaim == null || string.IsNullOrWhiteSpace(openIdClaim.Value)) return Redirect(redirectUrl); //TODO 記錄受權成功後的信息 string email = authenticateResult.Principal.FindFirst(ClaimTypes.Email)?.Value; string name = authenticateResult.Principal.FindFirst(ClaimTypes.Name)?.Value; string gitHubName = authenticateResult.Principal.FindFirst(GitHubAuthenticationConstants.Claims.Name)?.Value; string gitHubUrl = authenticateResult.Principal.FindFirst(GitHubAuthenticationConstants.Claims.Url)?.Value; //startup 中 AddGitHub配置項 options.ClaimActions.MapJsonKey(LinConsts.Claims.AvatarUrl, "avatar_url"); string avatarUrl = authenticateResult.Principal.FindFirst(LinConsts.Claims.AvatarUrl)?.Value; return Redirect($"{redirectUrl}?openId={openIdClaim.Value}"); }