前言
微信相关配置请参考 微信公众平台 的这篇文章。注意授权回调域名一定要修改正确。
微信网页授权是通过OAuth2.0机制实现的,所以我们可以使用 https://github.com/china-live/QQConnect 这个开源项目提供的中间件来实现微信第三方登录的流程。
开发流程
1、新建一个.net core webapi 项目。在NuGet中查找并安装 AspNetCore.Authentication.WeChat
包。
2、修改 appsettings.json
配置文件,增加以下配置:
1 \"Authentication\": { 2 \"WeChat\": { 3 \"AppId\": \"微信AppID\", 4 \"AppSecret\": \"微信AppSecret\" 5 } 6 }, 7 \"Logging\": { 8 \"LogLevel\": { 9 \"Default\": \"Debug\", //日志级别从低到高,依次为:Debug,Information,Warning,Error,None 10 \"Microsoft.EntityFrameworkCore\": \"Error\", 11 \"System\": \"Error\" 12 } 13 }
3、修改 Startup
1 services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); 2 services.AddAuthentication() 3 .AddWeChat(wechatOptions => 4 { 5 wechatOptions.AppId = Configuration[\"Authentication:WeChat:AppId\"]; 6 wechatOptions.AppSecret = Configuration[\"Authentication:WeChat:AppSecret\"]; 7 wechatOptions.UseCachedStateDataFormat = true; 8 });
4、新增 AccountController
1 [Route(\"api/[controller]\")] 2 [ApiController] 3 public class AccountController : ControllerBase 4 { 5 private const string LoginProviderKey = \"LoginProvider\"; 6 private const string Provider_WeChat = \"WeChat\"; 7 private readonly ILogger _logger; 8 private readonly IHttpContextAccessor _contextAccessor; 9 10 public AccountController(ILogger<AccountController> logger, 11 IHttpContextAccessor contextAccessor) 12 { 13 _logger = logger; 14 _contextAccessor = contextAccessor; 15 } 16 /// <summary> 17 /// 微信登录 18 /// </summary> 19 /// <param name=\"redirectUrl\">授权成功后的跳转地址</param> 20 /// <returns></returns> 21 [HttpGet(\"LoginByWeChat\")] 22 public IActionResult LoginByWeChat(string redirectUrl) 23 { 24 var request = _contextAccessor.HttpContext.Request; 25 var url = $\"{request.Scheme}://{request.Host}{request.PathBase}{request.Path}Callback?provider={Provider_WeChat}&redirectUrl={redirectUrl}\"; 26 var properties = new AuthenticationProperties { RedirectUri = url }; 27 properties.Items[LoginProviderKey] = Provider_WeChat; 28 return Challenge(properties, Provider_WeChat); 29 } 30 /// <summary> 31 /// 微信授权成功后自动回调的地址 32 /// </summary> 33 /// <param name=\"provider\"></param> 34 /// <param name=\"redirectUrl\">授权成功后的跳转地址</param> 35 /// <returns></returns> 36 [HttpGet(\"LoginByWeChatCallback\")] 37 public async Task<IActionResult> LoginByWeChatCallbackAsync(string provider = null, string redirectUrl = \"\") 38 { 39 var authenticateResult = await _contextAccessor.HttpContext.AuthenticateAsync(provider); 40 if (!authenticateResult.Succeeded) return Redirect(redirectUrl); 41 var openIdClaim = authenticateResult.Principal.FindFirst(ClaimTypes.NameIdentifier); 42 if (openIdClaim == null || openIdClaim.Value.IsNullOrWhiteSpace()) 43 return Redirect(redirectUrl); 44 //TODO 记录授权成功后的微信信息 45 var city = authenticateResult.Principal.FindFirst(\"urn:wechat:city\")?.Value; 46 var country = authenticateResult.Principal.FindFirst(ClaimTypes.Country)?.Value; 47 var headimgurl = authenticateResult.Principal.FindFirst(ClaimTypes.Uri)?.Value; 48 var nickName = authenticateResult.Principal.FindFirst(ClaimTypes.Name)?.Value; 49 var openId = authenticateResult.Principal.FindFirst(ClaimTypes.NameIdentifier)?.Value; 50 var privilege = authenticateResult.Principal.FindFirst(\"urn:wechat:privilege\")?.Value; 51 var province = authenticateResult.Principal.FindFirst(\"urn:wechat:province\")?.Value; 52 var sexClaim = authenticateResult.Principal.FindFirst(ClaimTypes.Gender); 53 int sex = 0; 54 if (sexClaim != null && !sexClaim.Value.IsNullOrWhiteSpace()) 55 sex = int.Parse(sexClaim.Value); 56 var unionId = authenticateResult.Principal.FindFirst(\"urn:wechat:unionid\")?.Value; 57 _logger.LogDebug($\"WeChat Info=> openId: {openId},nickName: {nickName}\"); 58 return Redirect($\"{redirectUrl}?openId={openIdClaim.Value}\"); 59 } 60 }
5、将网站发布到外网,请求
https://你的授权域名/api/account/LoginByWeChat?redirectUrl=授权成功后要跳转的页面
即可调起微信授权页面。
注意
微信授权必须使用https
微信开放平台和微信公众平台都有提供网站用微信登录的接口,前者适用于任何网站,后者只适用于微信服务号的内嵌网站
本篇相关源码地址:https://github.com/ren8179/QrF.OAuth.WeChat/tree/master