Tauri中微信第三方登录,软软 AI 登录验证
先看下最后的效果图
准备
- 微信的开放平台注册
- 网站的备案
- 在开放平台上添加网页应用
- 把该域名添加到白名单
- 生成好 appkey 等
服务端编写微信认证的回调
这里主要是根据微信的开发文档,
- 通过 code 获取 用户的unionid 和 openid等。
- 通过 unionid 查找到用户的信息,或者注册一个新的用户。
- 根据用户 id 的一些相关信息生成 JWT 的 token
- 根据 state 的参数不同可以做一些不同的跳转处理
- 笔者这边是跳转到了一个备案域名下的一个页面中。
下面给出 rust 的一段伪代码
//
let code = ...;
let state = ...;
let appid = crate::constants::WX_WEBSITE_RRAI_APP_ID;
let app_secret = crate::constants::WX_WEBSITE_RRAI_APP_SECRET;
//通过 CODE 获取 token
let (openid, unionid, _access_token) =
wx_access_token_by_code(appid, app_secret, code.as_str())
.await
.map_err(|err| error::ErrorInternalServerError(err))?;
...
//查看用户 ID,不存在则注册用户
let claims = if let Ok(account) =
query_by_unionid(pool, &unionid, &String::from(WX_WEBSITE_SRC_TYPE)).await
{
//存在
Claims {
userid: ...
}
} else {
//不存在,添加账号和用户
.....
Claims {
userid: ...
}
};
//生成TOKEN
if let Ok(_token) = encode(
&Header::default(),
&claims,
&EncodingKey::from_secret(crate::constants::RRAI_JWT_SECRET.as_ref()),
) {
if state != "....." {
//
Ok(Redirect::to(format!(
"{}?key=token&token={}",
url_decode(state.as_str()).map_err(|err| error::ErrorInternalServerError(err))?,
url_encode(_token.as_str()),
))
.temporary())
} else {
//
Ok(Redirect::to(format!(
"https://www......../index.html#/wx_login_proxy?key=token&token={}&.....",
url_encode(_token.as_str()),
))
.temporary())
}
} else {
//
Err(error::ErrorUnauthorized("认证失败"))
}
}
在备案的域名下写一个跳转的前端
这个代理的网页比较简单,就是做一些验证,然后将 token 携带并调整到 tauri 的项目网页中
这里注意的是 tauri:// 这块,如果某一些原因不是这个了,那么就修改下。
window.location.href = `tauri://localhost/?key=token&token=${params['token']}#/tklogin`
在 Tauri 的项目中集成登录
在 Tauri 的项目中比较简单,就是和普通网站接入微信登录一样,
这里对应开发的环境(http 前缀)特殊处理了下。
let redirectUrl = `${BASE_REDIRECT_URL}`;
let origin = window.location.origin;
let src = '';
if (origin.indexOf('http') == 0) {
//DEBUG
let localUrl = origin + '/#/tklogin';
let state = `${encodeURIComponent(localUrl)}`;
src = `https://open.weixin.qq.com/connect/qrconnect?appid=${APPID}&redirect_uri=${encodeURIComponent(redirectUrl)}&response_type=code&scope=snsapi_login&state=${state}#wechat_redirect`;
} else {
src = `https://open.weixin.qq.com/connect/qrconnect?appid=${APPID}&redirect_uri=${encodeURIComponent(redirectUrl)}&response_type=code&scope=snsapi_login&state=`;
}
花絮
在 Tauri 中使用 iframe 方案
- 最开始想使用在 Tauri 的项目中使用 iframe, 然后使用 iframe 的 postmessage 的方式和主页面进行通信,通过 state 传送参数(把当前页面的地址传递过去),后端微信认证回调时直接使用 302 的方式进行跳转。这样就可以免掉一个中间的网页。最终失败了。
- 在tauri dev 的时候是好用的, 但是发布之后不行。 最后找到原因是 dev 的时候地址是 http://localhost。 但是发布之后是tauri://。 如果是 tauri:// 这个时候后端的 http 重定向就失效了。无法实现。
详细的代码可以参见 github