Use SPA + .NET Core3.1 achieve similar GitHub third party authorized to log on using AspNet.Security.OAuth.GitHub, front-end as follows: VUE + Vue-Router + axios
AspNet.Security.OAuth.GitHub
GitHub authorization Login
What configuration process does not say. . There is a push.
The following is an example
client_id:0be6b05fc717bfc4fb67
client_secret:dcaced9f176afba64e89d88b9b06ffc4a887a609
Get
https://github.com/login/oauth/authorize?client_id=0be6b05fc717bfc4fb67&redirect_uri=https://localhost:5001/signin-github
Redirected to
https://localhost:5001/signin-github?code=07537a84d12bbae08361
The following code into the request, obtain the access_token
the POST mode (request to Postman)
https://github.com/login/oauth/access_token?client_id=0be6b05fc717bfc4fb67&client_secret=dcaced9f176afba64e89d88b9b06ffc4a887a609&code=07537a84d12bbae08361
Get way
https://api.github.com/user?access_token=787506afa3271d077b98f18af56d7cfdc8db43b4
Then you can get the user information
{
"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": "[email protected]",
"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"
}
.NET Core3.1
The following code is the main code, complete code to see the DEMO link below.
When using WebApi, I looked at a number of projects, all based on MVC structure, not what I want. Read some blog above description, the steps are the same pattern, with the front and rear ends are separated.
- The front running: http: // localhost: 8081
Back-end run: https: // localhost: 5001
Before and after the end of the separation of the SPA with authorized third-party login process is as follows
When a local test, gitHub callback address set http (s): // ip: port / signin-github
- 如: https://localhost:5001/signin-github。
This obviously fill the back end of the address 1 above, that the back end how the results tell the front of it?
前端请求https://localhost:5001/signin?provider=GitHub&redirectUrl=http://localhost:8080/login-result
- Provide parameters provider to GitHub,
- After redirectUrl to GitHub unauthorized access, callback signin-github, go to the back end of the redirection address, fill the front end of a route here.
2. backend only provides a signin, signin-callback routing, no signin-github, github that routes are configured on how the callback come back yet?
google- login, Microsoft documents , including a change default callback URI of the , by AddGitHub in CallbackPath property configuration.
It describes the callback address should be configured signin-google, so there should be signin-github, he is configurable, does not need to write their own program processing signin-google this route, there are internal middleware has to deal with.
3. After a callback to signin-github, how to deal with the back-end, front-end to make a refresh. Access to information after login it.
According to the above specific procedure code acquisition access_token, access to information based on user access_token of these processes treatment, we do not need to deal with their own. We can use direct access to user information.
A method SignIn, as long as the return Challenge (Properties, Provider); ,
- provider as GitHub,
- properties var properties = new AuthenticationProperties { RedirectUri = url };
This url is another route to get user information, as long as the stitching good address.
var authenticateResult = await _contextAccessor.HttpContext.AuthenticateAsync(provider);
string email = authenticateResult.Principal.FindFirst(ClaimTypes.Email)?.Value;
string name = authenticateResult.Principal.FindFirst(ClaimTypes.Name)?.Value;
Need to inject
private readonly IHttpContextAccessor _contextAccessor;
public AuthenticationController( IHttpContextAccessor contextAccessor)
{
_contextAccessor = contextAccessor;
}
Deployment Code (simplified)
Open NuGet package management, installation package
Install-Package AspNet.Security.OAuth.GitHub
appSettings.json
"Authentication": {
"GitHub": {
"ClientId": "0be6b05fc717bfc4fb67",
"ClientSecret": "dcaced9f176afba64e89d88b9b06ffc4a887a609"
}
}
add extension methods
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"];
});
}
}
By default, such as Avatar, email, it is not obtained.
.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 configure this service
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddJwtConfiguration(Configuration);
Creating AuthenticationController.cs
increase SignIn, for post-processing user authorization is successful, re back signin-callback, and back to the parameter.
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);
}
In signin method, the user clicks the authorization (the first time), will be transferred in accordance with its URL to redirect to this address, signin-callback, the parameters will carry together. provider as GitHub, redirectUrl to: 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}");
}
reference
- .net Core2.2 WebApi achieved through micro letter login OAuth2.0
- AspNetCore3.0 和 JWT
- User System Design: third-party authorization, account binding and unbinding (lower)