添加微信获取access token接口

This commit is contained in:
liyunjia 2024-10-06 21:17:23 +08:00
parent f003467909
commit c2d249d72b
12 changed files with 70 additions and 12 deletions

2
Cargo.lock generated
View File

@ -1121,9 +1121,11 @@ dependencies = [
"http", "http",
"http-body", "http-body",
"http-body-util", "http-body-util",
"hyper",
"i18n", "i18n",
"jsonwebtoken", "jsonwebtoken",
"lazy_static", "lazy_static",
"macro",
"moka", "moka",
"once_cell", "once_cell",
"reqwest", "reqwest",

View File

@ -20,5 +20,5 @@ expires = 1800
refresh_expires = 3600 refresh_expires = 3600
[social.wechat] [social.wechat]
app_id = "wx0d0b0b0b0b0b0b0b" app_id = "wxf0547aa24593a446"
app_secret = "0d0b0b0b0d0b0b0b0d0b0b0b0b0b0b0b" app_secret = "e4a29192f9220d4d8c9eab37f8385c37"

View File

@ -13,4 +13,5 @@ ValidateAccountLangTagRequired,lang tag is required,用户语言标识不能为
ValidatePageablePageRequired,invalid page number,页码无效 ValidatePageablePageRequired,invalid page number,页码无效
ValidatePageablePageSizeRequired,invalid quantity per page,每页数量无效 ValidatePageablePageSizeRequired,invalid quantity per page,每页数量无效
BadRequest,bad request,无效请求 BadRequest,bad request,无效请求
InvalidParams,invalid params,无效参数 InvalidParams,invalid params,无效参数
FailedGetWxAaccessToken,Failed to get WeChat access_token,获取微信access_token失败
1 id en-US zh-CN
13 ValidatePageablePageRequired invalid page number 页码无效
14 ValidatePageablePageSizeRequired invalid quantity per page 每页数量无效
15 BadRequest bad request 无效请求
16 InvalidParams invalid params 无效参数
17 FailedGetWxAaccessToken Failed to get WeChat access_token 获取微信access_token失败

View File

@ -2,21 +2,40 @@ use strum_macros::{AsRefStr, Display, EnumIter, EnumString};
#[derive(Debug, EnumIter, EnumString, Display, PartialEq, AsRefStr)] #[derive(Debug, EnumIter, EnumString, Display, PartialEq, AsRefStr)]
pub enum MessageId { pub enum MessageId {
/// 无效请求
BadRequest, BadRequest,
/// 系统内部错误
ServerInternalError, ServerInternalError,
Hello, Hello,
/// 账户已禁用
AccountDisabled, AccountDisabled,
/// 账户无权限
AccountNoPermission, AccountNoPermission,
/// 用户名或密码错误
IncorrectUsernameOrPassword, IncorrectUsernameOrPassword,
/// 无效令牌
InvalidToken, InvalidToken,
/// 无效参数
InvalidParams, InvalidParams,
/// 反馈内容不能为空
ValidateFeedbackContentRequired, ValidateFeedbackContentRequired,
/// 用户名称不能为空
ValidateAccountNameRequired, ValidateAccountNameRequired,
/// 密码不能为空
ValidateAccountPasswordRequired, ValidateAccountPasswordRequired,
/// 用户ID Token不能为空
ValidateAccountIdTokenRequired, ValidateAccountIdTokenRequired,
/// 用户语言标识不能为空
ValidateAccountLangTagRequired, ValidateAccountLangTagRequired,
/// 页码无效
ValidatePageablePageRequired, ValidatePageablePageRequired,
/// 每页数量无效
ValidatePageablePageSizeRequired, ValidatePageablePageSizeRequired,
/// social begin
/// 获取微信access_token失败
FailedGetWxAaccessToken,
} }

View File

@ -34,6 +34,8 @@ hex-literal = { workspace = true }
tokio-cron-scheduler = { workspace = true } tokio-cron-scheduler = { workspace = true }
tower-http = { workspace = true, features = ["trace"] } tower-http = { workspace = true, features = ["trace"] }
tower = { workspace = true } tower = { workspace = true }
hyper = { workspace = true }
domain = { path = "../domain" } domain = { path = "../domain" }
i18n = { path = "../i18n" } i18n = { path = "../i18n" }
macro = { path = "../macro" }

View File

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

View File

@ -4,7 +4,8 @@ use chrono::Utc;
use futures_util::lock::Mutex; use futures_util::lock::Mutex;
use hmac::{Hmac, Mac}; use hmac::{Hmac, Mac};
use lazy_static::lazy_static; use lazy_static::lazy_static;
use serde::Deserialize; use macros::Responsable;
use serde::{Deserialize, Serialize};
use sha2::Sha256; use sha2::Sha256;
use crate::{ use crate::{
@ -15,7 +16,14 @@ use crate::{
use super::SocialResult; use super::SocialResult;
lazy_static! { lazy_static! {
pub static ref WECHAT_SOCIAL: WechatSocial = WechatSocial::default(); pub static ref WECHAT_SOCIAL: WechatSocial = {
let wechat_option = &config!().social.wechat;
WechatSocial {
app_id: wechat_option.app_id.to_owned(),
app_secret: wechat_option.app_secret.to_owned(),
..Default::default()
}
};
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -25,7 +33,7 @@ pub struct WechatSocial {
access_token: Arc<Mutex<WeChatAccessToken>>, access_token: Arc<Mutex<WeChatAccessToken>>,
} }
#[derive(Deserialize, Debug, Clone, Default)] #[derive(Deserialize, Serialize, Debug, Clone, Default, Responsable)]
pub struct WeChatAccessToken { pub struct WeChatAccessToken {
pub access_token: String, pub access_token: String,
pub expires_in: i64, pub expires_in: i64,
@ -79,8 +87,7 @@ impl WechatSocial {
/// ///
/// https://developers.weixin.qq.com/minigame/dev/api-backend/open-api/access-token/auth.getAccessToken.html /// https://developers.weixin.qq.com/minigame/dev/api-backend/open-api/access-token/auth.getAccessToken.html
/// https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-access-token/getAccessToken.html /// https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-access-token/getAccessToken.html
#[allow(dead_code)] pub async fn get_access_token(&self) -> SocialResult<WeChatAccessToken> {
async fn fetch_and_parse_wechat_access_token(&self) -> SocialResult<WeChatAccessToken> {
let mut wechat_access_token = self.access_token.lock().await; let mut wechat_access_token = self.access_token.lock().await;
if wechat_access_token.access_token.is_empty() if wechat_access_token.access_token.is_empty()
&& wechat_access_token.expires_in < Utc::now().timestamp() && wechat_access_token.expires_in < Utc::now().timestamp()

View File

@ -3,6 +3,7 @@ use library::typed_router::TypedRouter;
pub mod account_controller; pub mod account_controller;
pub mod feedback_controller; pub mod feedback_controller;
pub mod social_wx_controller;
pub fn init() -> Router { pub fn init() -> Router {
Router::new() Router::new()
@ -14,4 +15,6 @@ pub fn init() -> Router {
.typed_route(feedback_controller::add_feedback) .typed_route(feedback_controller::add_feedback)
.typed_route(feedback_controller::get_feedback_list_by_page) .typed_route(feedback_controller::get_feedback_list_by_page)
.typed_route(feedback_controller::get_feedback_list) .typed_route(feedback_controller::get_feedback_list)
// 微信相关路由
.typed_route(social_wx_controller::get_wechat_access_token)
} }

View File

@ -0,0 +1,9 @@
use library::{context::Context, model::response::ResResult, social::wechat::WeChatAccessToken};
use macros::get;
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
}

View File

@ -1,3 +1,4 @@
pub mod account_service; pub mod account_service;
pub mod feedback_service; pub mod feedback_service;
pub mod sys_account_service; pub mod sys_account_service;
pub mod social_wx_service;

View File

@ -1,2 +0,0 @@
/// 用于接收各个服务平台的回调、消息推送

View File

@ -0,0 +1,15 @@
use i18n::{message, message_ids::MessageId};
use library::{context::Context, model::response::{ResErr, ResResult}, social::wechat::{WeChatAccessToken, WECHAT_SOCIAL}};
pub async fn get_wechat_access_token(context: Context) -> ResResult<WeChatAccessToken> {
let lang_tag = context.get_lang_tag();
let access_token = match WECHAT_SOCIAL.get_access_token().await {
Ok(access_token) => access_token,
Err(err) => {
tracing::error!("获取微信access_token失败,err:{}", err);
return Err(ResErr::service(message!(lang_tag, MessageId::FailedGetWxAaccessToken)));
}
};
Ok(access_token)
}