对接微信小程序和小游戏登录

This commit is contained in:
liyunjia 2024-10-07 09:32:50 +08:00
parent c2d249d72b
commit 0d9647535f
9 changed files with 96 additions and 26 deletions

View File

@ -1,3 +1,4 @@
pub mod account;
pub mod feedback;
pub mod pageable;
pub mod pageable;
pub mod social_wx;

View File

@ -0,0 +1,11 @@
use serde::{Deserialize, Serialize};
use validator::Validate;
#[derive(Debug, Serialize, Deserialize, Validate)]
pub struct WxMinAppLogin {
/// 微信code
#[validate(required(message = "ValidateWxMinAppLoginCodeRequired"), length(min = 1, message = "ValidateWxMinAppLoginCodeRequired"))]
pub code: Option<String>,
}

View File

@ -14,4 +14,6 @@ ValidatePageablePageRequired,invalid page number,页码无效
ValidatePageablePageSizeRequired,invalid quantity per page,每页数量无效
BadRequest,bad request,无效请求
InvalidParams,invalid params,无效参数
FailedGetWxAaccessToken,Failed to get WeChat access_token,获取微信access_token失败
FailedGetWxAaccessToken,Failed to get WeChat access_token,获取微信access_token失败
FailedWeChatLogin,Failed to check WeChat login code,微信登录失败
ValidateWxMinAppLoginCodeRequired,login code is required,微信登陆code不能为空
1 id en-US zh-CN
14 ValidatePageablePageSizeRequired invalid quantity per page 每页数量无效
15 BadRequest bad request 无效请求
16 InvalidParams invalid params 无效参数
17 FailedGetWxAaccessToken Failed to get WeChat access_token 获取微信access_token失败
18 FailedWeChatLogin Failed to check WeChat login code 微信登录失败
19 ValidateWxMinAppLoginCodeRequired login code is required 微信登陆code不能为空

View File

@ -33,9 +33,13 @@ pub enum MessageId {
ValidatePageablePageRequired,
/// 每页数量无效
ValidatePageablePageSizeRequired,
/// 无效的微信code
ValidateWxMinAppLoginCodeRequired,
/// social begin
/// 获取微信access_token失败
FailedGetWxAaccessToken,
/// 微信登录失败校验code失败
FailedWeChatLogin,
}

View File

@ -10,7 +10,8 @@ use crate::{cache::account_cache::LOGIN_CACHE, config, context::Context, model::
const WHITE_LIST: &[(&str, &str)] = &[
("POST", "/account/sys"),
("POST", "/account/google"),
("GET", "/wechat/access_token")
("GET", "/wechat/access_token"),
("POST", "/wechat/code_2_session"),
];
/// 认证中间件包括网络请求白名单、token验证、登录缓存

View File

@ -47,20 +47,32 @@ pub struct WeChatBaseResult {
pub errmsg: String,
}
#[derive(Deserialize, Debug, Clone)]
/// 微信登录登录
///
/// 登录成功
/// ```
/// {
/// "openid": "odbV75XGs-Lwj0CmOxwIXjdDfVEY",
/// "session_key": "iM6cs8nhw0VtAty16RjswQ==",
/// "unionid": null,
/// "errcode": null,
/// "errmsg": null
/// }
/// ```
#[derive(Deserialize, Serialize, Debug, Clone, Responsable)]
pub struct MiniAppLoginResult {
// 用户唯一标识
pub openid: String,
pub openid: Option<String>,
// 会话密钥
pub session_key: String,
pub session_key: Option<String>,
// 用户在开放平台的唯一标识符,若当前小程序已绑定到微信开放平台账号下会返回
// 如果开发者拥有多个移动应用、网站应用、和公众账号(包括小程序),可通过 UnionID 来区分用户的唯一性
// https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/union-id.html
pub unionid: String,
pub unionid: Option<String>,
// 错误码
pub errcode: i64,
pub errcode: Option<i64>,
// 错误信息
pub errmsg: String,
pub errmsg: Option<String>,
}
impl Default for WechatSocial {
@ -122,17 +134,25 @@ impl WechatSocial {
))
.await
.unwrap();
let result: MiniAppLoginResult = response.json().await.unwrap();
if result.errcode != 0 {
tracing::error!(
"微信登录失败,errcode:{},errmsg:{}",
result.errcode,
result.errmsg
);
return Err(Box::new(ResErr::social(format!(
"微信登录失败,errcode:{},errmsg:{}",
result.errcode, result.errmsg
))));
let result: MiniAppLoginResult = match response.json().await {
Ok(result) => result,
Err(err) => {
tracing::error!("微信登录失败,err:{:?}", err);
return Err(Box::new(ResErr::social(format!("微信登录失败,err:{}", err))));
}
};
if let Some(errcode) = result.errcode {
if errcode != 0 {
tracing::error!(
"微信登录失败,errcode:{:?},errmsg:{:?}",
result.errcode,
result.errmsg
);
return Err(Box::new(ResErr::social(format!(
"微信登录失败,errcode:{:?},errmsg:{:?}",
result.errcode, result.errmsg
))));
}
}
Ok(result)
}

View File

@ -17,4 +17,5 @@ pub fn init() -> Router {
.typed_route(feedback_controller::get_feedback_list)
// 微信相关路由
.typed_route(social_wx_controller::get_wechat_access_token)
.typed_route(social_wx_controller::code_2_session)
}

View File

@ -1,9 +1,18 @@
use library::{context::Context, model::response::ResResult, social::wechat::WeChatAccessToken};
use macros::get;
use domain::dto::social_wx::WxMinAppLogin;
use library::{context::Context, extractor::body_extractor::JsonBody, model::response::ResResult, social::wechat::{MiniAppLoginResult, WeChatAccessToken}};
use macros::{get, post};
use crate::service::social_wx_service;
#[get("/wechat/access_token")]
pub async fn get_wechat_access_token(context: Context) -> ResResult<WeChatAccessToken> {
social_wx_service::get_wechat_access_token(context).await
}
#[post("/wechat/code_2_session")]
pub async fn code_2_session(
context: Context,
JsonBody(mini_app_login): JsonBody<WxMinAppLogin>
) -> ResResult<MiniAppLoginResult> {
social_wx_service::code_2_session(context, mini_app_login.code.unwrap()).await
}

View File

@ -1,6 +1,9 @@
use i18n::{message, message_ids::MessageId};
use library::{context::Context, model::response::{ResErr, ResResult}, social::wechat::{WeChatAccessToken, WECHAT_SOCIAL}};
use library::{
context::Context,
model::response::{ResErr, ResResult},
social::wechat::{MiniAppLoginResult, WeChatAccessToken, WECHAT_SOCIAL},
};
pub async fn get_wechat_access_token(context: Context) -> ResResult<WeChatAccessToken> {
let lang_tag = context.get_lang_tag();
@ -8,8 +11,26 @@ pub async fn get_wechat_access_token(context: Context) -> ResResult<WeChatAccess
Ok(access_token) => access_token,
Err(err) => {
tracing::error!("获取微信access_token失败,err:{}", err);
return Err(ResErr::service(message!(lang_tag, MessageId::FailedGetWxAaccessToken)));
return Err(ResErr::service(message!(
lang_tag,
MessageId::FailedGetWxAaccessToken
)));
}
};
Ok(access_token)
}
}
pub async fn code_2_session(context: Context, code: String) -> ResResult<MiniAppLoginResult> {
let lang_tag = context.get_lang_tag();
let result = match WECHAT_SOCIAL.code_2_session(&code).await {
Ok(result) => result,
Err(err) => {
tracing::error!("微信登录失败,err:{}", err);
return Err(ResErr::service(message!(
lang_tag,
MessageId::FailedWeChatLogin
)));
}
};
Ok(result)
}