From 0d9647535f7ddb0e0b42c15410ce5d0765a50b95 Mon Sep 17 00:00:00 2001 From: liyunjia Date: Mon, 7 Oct 2024 09:32:50 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=B9=E6=8E=A5=E5=BE=AE=E4=BF=A1=E5=B0=8F?= =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=92=8C=E5=B0=8F=E6=B8=B8=E6=88=8F=E7=99=BB?= =?UTF-8?q?=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- domain/src/dto/mod.rs | 3 +- domain/src/dto/social_wx.rs | 11 ++++ i18n.csv | 4 +- i18n/src/message_ids.rs | 4 ++ library/src/middleware/req_ctx.rs | 3 +- library/src/social/wechat.rs | 54 +++++++++++++------ server/src/controller/mod.rs | 1 + server/src/controller/social_wx_controller.rs | 13 ++++- server/src/service/social_wx_service.rs | 29 ++++++++-- 9 files changed, 96 insertions(+), 26 deletions(-) create mode 100644 domain/src/dto/social_wx.rs diff --git a/domain/src/dto/mod.rs b/domain/src/dto/mod.rs index e9ddf8c..14b4f66 100644 --- a/domain/src/dto/mod.rs +++ b/domain/src/dto/mod.rs @@ -1,3 +1,4 @@ pub mod account; pub mod feedback; -pub mod pageable; \ No newline at end of file +pub mod pageable; +pub mod social_wx; \ No newline at end of file diff --git a/domain/src/dto/social_wx.rs b/domain/src/dto/social_wx.rs new file mode 100644 index 0000000..1cc5145 --- /dev/null +++ b/domain/src/dto/social_wx.rs @@ -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, +} \ No newline at end of file diff --git a/i18n.csv b/i18n.csv index 83e16d3..ac8204f 100644 --- a/i18n.csv +++ b/i18n.csv @@ -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失败 \ No newline at end of file +FailedGetWxAaccessToken,Failed to get WeChat access_token,获取微信access_token失败 +FailedWeChatLogin,Failed to check WeChat login code,微信登录失败 +ValidateWxMinAppLoginCodeRequired,login code is required,微信登陆code不能为空 \ No newline at end of file diff --git a/i18n/src/message_ids.rs b/i18n/src/message_ids.rs index 7bd32c2..23405ba 100644 --- a/i18n/src/message_ids.rs +++ b/i18n/src/message_ids.rs @@ -33,9 +33,13 @@ pub enum MessageId { ValidatePageablePageRequired, /// 每页数量无效 ValidatePageablePageSizeRequired, + /// 无效的微信code + ValidateWxMinAppLoginCodeRequired, /// social begin /// 获取微信access_token失败 FailedGetWxAaccessToken, + /// 微信登录失败,校验code失败 + FailedWeChatLogin, } diff --git a/library/src/middleware/req_ctx.rs b/library/src/middleware/req_ctx.rs index 97fb07b..a1f6ddb 100644 --- a/library/src/middleware/req_ctx.rs +++ b/library/src/middleware/req_ctx.rs @@ -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验证、登录缓存 diff --git a/library/src/social/wechat.rs b/library/src/social/wechat.rs index 8ac15ee..71cc039 100644 --- a/library/src/social/wechat.rs +++ b/library/src/social/wechat.rs @@ -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, // 会话密钥 - pub session_key: String, + pub session_key: Option, // 用户在开放平台的唯一标识符,若当前小程序已绑定到微信开放平台账号下会返回 // 如果开发者拥有多个移动应用、网站应用、和公众账号(包括小程序),可通过 UnionID 来区分用户的唯一性 // https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/union-id.html - pub unionid: String, + pub unionid: Option, // 错误码 - pub errcode: i64, + pub errcode: Option, // 错误信息 - pub errmsg: String, + pub errmsg: Option, } 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) } diff --git a/server/src/controller/mod.rs b/server/src/controller/mod.rs index f2742d5..cdfb518 100644 --- a/server/src/controller/mod.rs +++ b/server/src/controller/mod.rs @@ -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) } diff --git a/server/src/controller/social_wx_controller.rs b/server/src/controller/social_wx_controller.rs index 9b7ce69..d0964a0 100644 --- a/server/src/controller/social_wx_controller.rs +++ b/server/src/controller/social_wx_controller.rs @@ -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 { 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 +) -> ResResult { + social_wx_service::code_2_session(context, mini_app_login.code.unwrap()).await } \ No newline at end of file diff --git a/server/src/service/social_wx_service.rs b/server/src/service/social_wx_service.rs index 14e61be..211d917 100644 --- a/server/src/service/social_wx_service.rs +++ b/server/src/service/social_wx_service.rs @@ -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 { let lang_tag = context.get_lang_tag(); @@ -8,8 +11,26 @@ pub async fn get_wechat_access_token(context: Context) -> ResResult 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) -} \ No newline at end of file +} + +pub async fn code_2_session(context: Context, code: String) -> ResResult { + 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) +}