Skip to content

Commit

Permalink
WeChat related setting is done
Browse files Browse the repository at this point in the history
  • Loading branch information
songquanpeng committed Nov 5, 2022
1 parent 23bd08b commit 31654c8
Show file tree
Hide file tree
Showing 9 changed files with 175 additions and 4 deletions.
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,17 @@
+ [ ] Access Token 中控服务器

## 用法
1.[GitHub Releases](https://github.com/songquanpeng/wechat-server/releases/latest) 下载可执行文件.
1.[GitHub Releases](https://github.com/songquanpeng/wechat-server/releases/latest) 下载可执行文件
2. 运行:
1. `chmod u+x wechat-server`
2. `./wechat-server --port 3000`
3. 初始账户用户名为 `root`,密码为 `123456`
3. 初始账户用户名为 `root`,密码为 `123456`,记得登录后立刻修改密码。
4. 前往[微信公众号配置页面 -> 设置与开发 -> 基本配置](https://mp.weixin.qq.com/)获取 AppID 和 AppSecret,并在我们的配置页面填入上述信息,另外还需要配置 IP 白名单,按照页面上的提示完成即可。
5. 前往[微信公众号配置页面 -> 设置与开发 -> 基本配置](https://mp.weixin.qq.com/)填写以下配置:
1. `URL` 填:`https://<your.domain>/api/wechat_verification`
2. `Token` 首先在我们的配置页面随便填写一个 Token,然后在微信公众号的配置页面填入同一个 Token 即可。
3. `EncodingAESKey` 点随机生成,然后在我们的配置页面填入该值。
4. 消息加解密方式选择明文模式。

## 配置
系统本身开箱即用。
Expand Down
8 changes: 8 additions & 0 deletions common/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ var SystemName = "微信服务器"
var ServerAddress = "http://localhost:3000"
var FooterHTML = ""

// Any options with "Secret", "Token", "Key" in its key won't be return by GetOptions

var WeChatToken = ""
var WeChatAppID = ""
var WeChatAppSecret = ""
var WeChatEncodingAESKey = ""
var WeChatOwnerID = ""

var SessionSecret = uuid.New().String()
var SQLitePath = ".wechat-server.db"

Expand Down
22 changes: 22 additions & 0 deletions controller/misc.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package controller

import (
"crypto/sha1"
"encoding/hex"
"fmt"
"github.com/gin-gonic/gin"
"net/http"
"sort"
"strings"
"wechat-server/common"
"wechat-server/model"
)
Expand Down Expand Up @@ -36,6 +40,24 @@ func GetNotice(c *gin.Context) {
return
}

func WeChatVerification(c *gin.Context) {
// https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html
signature := c.Query("signature")
timestamp := c.Query("timestamp")
nonce := c.Query("nonce")
echoStr := c.Query("echostr")
arr := []string{common.WeChatToken, timestamp, nonce}
sort.Strings(arr)
str := strings.Join(arr, "")
hash := sha1.Sum([]byte(str))
hexStr := hex.EncodeToString(hash[:])
if signature == hexStr {
c.String(http.StatusOK, echoStr)
} else {
c.Status(http.StatusForbidden)
}
}

func SendEmailVerification(c *gin.Context) {
email := c.Query("email")
if err := common.Validate.Var(email, "required,email"); err != nil {
Expand Down
3 changes: 2 additions & 1 deletion controller/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"github.com/gin-gonic/gin"
"net/http"
"strings"
"wechat-server/common"
"wechat-server/model"
)
Expand All @@ -12,7 +13,7 @@ func GetOptions(c *gin.Context) {
var options []*model.Option
common.OptionMapRWMutex.Lock()
for k, v := range common.OptionMap {
if k == "SMTPToken" || k == "GitHubClientSecret" {
if strings.Contains(k, "Token") || strings.Contains(k, "Secret") || strings.Contains(k, "Key") {
continue
}
options = append(options, &model.Option{
Expand Down
2 changes: 1 addition & 1 deletion middleware/cors.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ func CORS() gin.HandlerFunc {
config.MaxAge = 12 * time.Hour
// if you want to allow all origins, comment the following two lines
config.AllowAllOrigins = false
//config.AllowedOrigins = []string{"https://wechat-server.vercel.app"}
config.AllowedOrigins = []string{"https://wechat-server.vercel.app"}
return cors.New(config)
}
15 changes: 15 additions & 0 deletions model/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ func InitOptionMap() {
common.OptionMap["ServerAddress"] = ""
common.OptionMap["GitHubClientId"] = ""
common.OptionMap["GitHubClientSecret"] = ""
common.OptionMap["WeChatToken"] = ""
common.OptionMap["WeChatAppID"] = ""
common.OptionMap["WeChatAppSecret"] = ""
common.OptionMap["WeChatEncodingAESKey"] = ""
common.OptionMap["WeChatOwnerID"] = ""
common.OptionMapRWMutex.Unlock()
options, _ := AllOption()
for _, option := range options {
Expand Down Expand Up @@ -106,5 +111,15 @@ func updateOptionMap(key string, value string) {
common.GitHubClientSecret = value
case "FooterHTML":
common.FooterHTML = value
case "WeChatToken":
common.WeChatToken = value
case "WeChatAppID":
common.WeChatAppID = value
case "WeChatAppSecret":
common.WeChatAppSecret = value
case "WeChatEncodingAESKey":
common.WeChatEncodingAESKey = value
case "WeChatOwnerID":
common.WeChatOwnerID = value
}
}
1 change: 1 addition & 0 deletions router/api-router.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ func SetApiRouter(router *gin.Engine) {
{
apiRouter.GET("/status", controller.GetStatus)
apiRouter.GET("/notice", controller.GetNotice)
apiRouter.GET("/wechat_verification", controller.WeChatVerification)
apiRouter.GET("/verification", middleware.CriticalRateLimit(), controller.SendEmailVerification)
apiRouter.GET("/reset_password", middleware.CriticalRateLimit(), controller.SendPasswordResetEmail)
apiRouter.GET("/user/reset", controller.SendNewPasswordEmail)
Expand Down
109 changes: 109 additions & 0 deletions web/src/components/WeChatSetting.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import React, { useEffect, useState } from 'react';
import { Form, Grid } from 'semantic-ui-react';
import { API, showError } from '../helpers';

const WeChatSetting = () => {
let [inputs, setInputs] = useState({
WeChatToken: '',
WeChatAppID: '',
WeChatAppSecret: '',
WeChatEncodingAESKey: '',
WeChatOwnerID: '',
});
let [loading, setLoading] = useState(false);

const getOptions = async () => {
const res = await API.get('/api/option');
const { success, message, data } = res.data;
if (success) {
let newInputs = {};
data.forEach((item) => {
if (item.key.startsWith('WeChat')) {
newInputs[item.key] = item.value;
}
});
setInputs(newInputs);
} else {
showError(message);
}
};

useEffect(() => {
getOptions().then();
}, []);

const updateOption = async (key, value) => {
setLoading(true);
const res = await API.put('/api/option', {
key,
value,
});
const { success, message } = res.data;
if (success) {
setInputs((inputs) => ({ ...inputs, [key]: value }));
} else {
showError(message);
}
setLoading(false);
};

const handleInputChange = async (e, { name, value }) => {
await updateOption(name, value);
};

return (
<Grid columns={1}>
<Grid.Column>
<Form loading={loading}>
<Form.Group widths="equal">
<Form.Input
label="令牌(Token)"
placeholder=""
value={inputs.WeChatToken}
name="WeChatToken"
onChange={handleInputChange}
/>
</Form.Group>
<Form.Group widths="equal">
<Form.Input
label="开发者 ID(AppID)"
placeholder=""
value={inputs.WeChatAppID}
name="WeChatAppID"
onChange={handleInputChange}
/>
</Form.Group>
<Form.Group widths="equal">
<Form.Input
label="开发者密码(AppSecret)"
placeholder=""
value={inputs.WeChatAppSecret}
name="WeChatAppSecret"
onChange={handleInputChange}
/>
</Form.Group>
<Form.Group widths="equal">
<Form.Input
label="消息加解密密钥(EncodingAESKey)"
placeholder=""
value={inputs.WeChatEncodingAESKey}
name="WeChatEncodingAESKey"
onChange={handleInputChange}
/>
</Form.Group>
<Form.Group widths="equal">
<Form.Input
label="Root 用户微信 ID"
placeholder=""
value={inputs.WeChatOwnerID}
name="WeChatOwnerID"
onChange={handleInputChange}
/>
</Form.Group>
</Form>
</Grid.Column>
</Grid>
);
};

export default WeChatSetting;
9 changes: 9 additions & 0 deletions web/src/pages/Setting/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import SystemSetting from '../../components/SystemSetting';
import { Link } from 'react-router-dom';
import { API, copy, isRoot, showError, showSuccess } from '../../helpers';
import { marked } from 'marked';
import WeChatSetting from '../../components/WeChatSetting';

const Setting = () => {
const [showUpdateModal, setShowUpdateModal] = useState(false);
Expand Down Expand Up @@ -67,6 +68,14 @@ const Setting = () => {
</Tab.Pane>
),
});
panes.push({
menuItem: '微信设置',
render: () => (
<Tab.Pane attached={false}>
<WeChatSetting />
</Tab.Pane>
),
});
panes.push({
menuItem: '其他设置',
render: () => (
Expand Down

0 comments on commit 31654c8

Please sign in to comment.