在Blazor實現微信小程序掃碼登錄
——使用極簡登錄模型
最近需要開發一個Blazor Server Side頁面,需要用到登錄功能,作為某微信小程序的后管。在網上搜了一遍,似乎沒有找到合適的,所以就自己造了個輪子。幾乎都是代碼,從來不需要寫注釋的我。
- 本文示例后端代碼在
.NET 6
,下用Minimal Api
實現。 - 我是CHARSET,轉載請保留全文本。
1. Blazor前端顯示二維碼
在GitHub
上隨便找了個組件,名字是BlazorZXingJs
。使用方法也非常簡單。將組件放入<NotAuthorized>
標簽內部。
<QRCodeWriter Text="@Code" Width="200" Heigth="200" @ref="writer" />
如果需要每隔一段時間生成,則更換Code
的值即可。
2. 使用SignalR將ConnectionId從后端傳給Blazor前端
在后端SignalR.Hub接受每次連接時傳回
public override async Task OnConnectedAsync() {
await Clients.Caller.SendAsync("ConnectionId", Context.ConnectionId);
await base.OnConnectedAsync();
}
Blazor前端接收到ConnectionId
hubConnection.On<string>("ConnectionId", id => connectionId = id);
需要注意到的是,Blazor前端在收到此Id后才顯示二維碼
if (!string.IsNullOrEmpty(connectionId)) {
code = Guid.NewGuid().ToString();
Membership.RegisterScanCode(code);
Code = $"{code}|{connectionId}";
InvokeAsync(StateHasChanged);
}
為了簡單起見,Code
使用上述邏輯生成。圖像識別的結果是注冊的二維碼Code
和connectionId
。
3. 小程序解析快速響應碼(QRCode)
function OnQRLogin() {
wx.scanCode({ onlyFromCamera: true, scanType: ['qrCode'],
success: function (res) {
const split = res.result.split('|')
wx.request({
url: `${host}/e/${token}/${split[0]}/${split[1]}`,
success: function (rt) {
if (rt.data && rt.data.success) {
wx.showModal({ title: '成功', content: '請注意登錄頁面是否成功的信息', icon: 'success' })
}
}
})
}
})
}
4. 后端服務根據ConnectionId將Token和二維碼Code回送給Blazor前端
application.MapGet("/e/{token}/{recog}/{cid}", async Task<SimpleResponse>
(string token, string recog, string cid, [FromServices] ChatHubHelper hub) => {
var response = new SimpleResponse();
await hub.SendRequest(cid, new LoginRequest { ScanCode = recog, Token = token });
response.Success = true;
return response;
});
5. Blazor前端收到此回執后正常使用極簡模型登錄
hubConnection.On<LoginRequest>("LoginRequest", async request => {
connectionId = "已掃描,請靜待結果……";
var response = await AuthStateProvider.Login(request);
if (response.Success) {
Membership.UnRegisterScanCode(code);
await Message.Success("登錄成功");
} else {
await Message.Warn(response.Message);
}
await InvokeAsync(StateHasChanged);
});
初版在2022年3月17日寫