打开页面,需要用户点允许授权。通过之后浏览器会把code 和 state参数带这get请求redirect_url
callback页面的逻辑
callback 接收code和state两个参数。
public async Task<IActionResult> Callback(string code, string state){...}//方法签名用这个code调用sdk里面的api获取token,同时可以拿到openid。
var tokenResult = await OAuthApi.GetAccessTokenAsync(AppId, AppSecret, code); if (tokenResult.errcode != ReturnCode.请求成功) { throw new BizException("获取微信用户信息失败"); } var openId = tokenResult.openid;通过open获取用户信息。
var userInfo = await userService.GetByOpenId(openId);//userService是自己的业务service然后调用HttpContext.SignInAsync登录。
public static async Task SignInAsync(this HttpContext context, string subject, string name, AuthenticationProperties properties, params Claim[] claims) { var clock = context.GetClock(); var user = new IdentityServerUser(subject) { DisplayName = name, AdditionalClaims = claims, AuthenticationTime = clock.UtcNow.UtcDateTime }; await context.SignInAsync(user, properties); }HttpContext是当前请求的上下文。
subject可以理解为用户的标识。
name可以理解是用户显示的名字。
AuthenticationProperties是此次认证的一些配置,比如有效时长之类的。
Claim可以理解为这个subject带的一些属性。
await HttpContext.SignInAsync(userMobile, userName, props, claims);调用完之后就登录成功。
然后通过带来的state参数判断需要跳转的client。
var client = await clientStore.FindClientByIdAsync(state); return Redirect($"{client.PostLogoutRedirectUris.FirstOrDefault()}?logined=true");这里带一个logined=true参数,用来给client做一些逻辑。
总结首先要感谢的肯定是盛派微信sdk的contributors,没有他们系统对接起来应该会慢很多。
然后我想说,IdentityServer是个好东西,现在公司.NET相关的系统都已经用这个实现统一的登录逻辑了,系统维护的代价小了许多。
说起来其实也是第一次对接微信公众号相关的东西,在走通这条路之前走了不少弯路,不过好在走通了。希望对其他人有帮助。