Merge remote-tracking branch 'origin/master'
This commit is contained in:
@ -19,4 +19,5 @@ type IRewardV1 interface {
|
||||
UpdateStoreReward(ctx context.Context, req *v1.UpdateStoreRewardReq) (res *v1.UpdateStoreRewardRes, err error)
|
||||
DeleteSystemReward(ctx context.Context, req *v1.DeleteSystemRewardReq) (res *v1.DeleteSystemRewardRes, err error)
|
||||
DeleteStoreReward(ctx context.Context, req *v1.DeleteStoreRewardReq) (res *v1.DeleteStoreRewardRes, err error)
|
||||
RewardCallback(ctx context.Context, req *v1.RewardCallbackReq) (res *v1.RewardCallbackRes, err error)
|
||||
}
|
||||
|
||||
@ -131,3 +131,26 @@ type DeleteStoreRewardReq struct {
|
||||
type DeleteStoreRewardRes struct {
|
||||
Success bool `json:"success" dc:"删除成功"`
|
||||
}
|
||||
|
||||
type RewardCallbackReq struct {
|
||||
g.Meta `path:"/reward/callback" method:"post" tags:"Reward" summary:"(系统)奖励回调"`
|
||||
UId string `json:"uid"`
|
||||
OrderId string `json:"order_id"`
|
||||
PrizeChannelId string `json:"prize_channel_id"`
|
||||
PrizeId string `json:"prize_id" v:"required|#券ID不能为空"`
|
||||
PrizeType uint32 `json:"prize_type"`
|
||||
PrizeSubType uint32 `json:"prize_sub_type"`
|
||||
Num uint32 `json:"num"`
|
||||
CustomInfo string `json:"custom_info"`
|
||||
}
|
||||
type RewardCallbackRes struct {
|
||||
ErrCode int32 `json:"errcode"` // 必填
|
||||
ErrMsg string `json:"errmsg"`
|
||||
Appid string `json:"appid"`
|
||||
OrderId string `json:"order_id"` // 必填
|
||||
Data []RewardCallbackData `json:"data"` // 必填
|
||||
}
|
||||
type RewardCallbackData struct {
|
||||
PrizeCode string `json:"prize_code"` // 必填
|
||||
Comment string `json:"comment"`
|
||||
}
|
||||
|
||||
29
internal/controller/reward/reward_v1_reward_callback.go
Normal file
29
internal/controller/reward/reward_v1_reward_callback.go
Normal file
@ -0,0 +1,29 @@
|
||||
package reward
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/glog"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
|
||||
"server/api/reward/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) RewardCallback(ctx context.Context, req *v1.RewardCallbackReq) (res *v1.RewardCallbackRes, err error) {
|
||||
appId := g.RequestFromCtx(ctx).GetHeader("Custom-Data-Appid")
|
||||
timestamp := g.RequestFromCtx(ctx).GetHeader("Custom-Data-Timestamp")
|
||||
nonce := g.RequestFromCtx(ctx).GetHeader("Custom-Data-Nonce")
|
||||
auth := g.RequestFromCtx(ctx).GetHeader("Custom-Data-Auth")
|
||||
|
||||
glog.Infof(ctx, "appId: %s, timestamp: %s, nonce: %s, auth: %s", appId, timestamp, nonce, auth)
|
||||
secret := ""
|
||||
data := fmt.Sprintf("%s%s%s%s%d%d%d%s%s%s#%s", req.UId, req.OrderId, req.PrizeId, req.PrizeChannelId, req.PrizeType, req.PrizeSubType, req.Num, appId, timestamp, nonce, secret)
|
||||
if data != auth {
|
||||
|
||||
}
|
||||
|
||||
return nil, gerror.NewCode(gcode.CodeNotImplemented)
|
||||
}
|
||||
@ -2,6 +2,7 @@ package storeAdmin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
@ -10,5 +11,6 @@ import (
|
||||
)
|
||||
|
||||
func (c *ControllerV1) Info(ctx context.Context, req *v1.InfoReq) (res *v1.InfoRes, err error) {
|
||||
g.RequestFromCtx(ctx)
|
||||
return nil, gerror.NewCode(gcode.CodeNotImplemented)
|
||||
}
|
||||
|
||||
@ -34,6 +34,7 @@ type RewardsColumns struct {
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
DeletedAt string // 软删除时间戳
|
||||
RemainStock string // 剩余库存数量
|
||||
}
|
||||
|
||||
// rewardsColumns holds the columns for the table rewards.
|
||||
@ -51,6 +52,7 @@ var rewardsColumns = RewardsColumns{
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
DeletedAt: "deleted_at",
|
||||
RemainStock: "remain_stock",
|
||||
}
|
||||
|
||||
// NewRewardsDao creates and returns a new DAO object for table data access.
|
||||
|
||||
@ -27,7 +27,6 @@ type UsersColumns struct {
|
||||
Nickname string // 昵称
|
||||
Avatar string // 用户头像URL
|
||||
PasswordHash string // 密码哈希
|
||||
Email string // 邮箱地址
|
||||
PhoneNumber string // 手机号
|
||||
WxPopenId string // 微信 PopenID
|
||||
QqPopenId string // QQ PopenID
|
||||
@ -48,7 +47,6 @@ var usersColumns = UsersColumns{
|
||||
Nickname: "nickname",
|
||||
Avatar: "avatar",
|
||||
PasswordHash: "password_hash",
|
||||
Email: "email",
|
||||
PhoneNumber: "phone_number",
|
||||
WxPopenId: "wx_popen_id",
|
||||
QqPopenId: "qq_popen_id",
|
||||
|
||||
@ -156,7 +156,6 @@ func (s *sUser) Info(ctx context.Context, in *model.UserInfoIn) (out *model.User
|
||||
Username: user.Username,
|
||||
Nickname: user.Nickname,
|
||||
Avatar: user.Avatar,
|
||||
Email: user.Email,
|
||||
PhoneNumber: user.PhoneNumber,
|
||||
WxPopenId: user.WxPopenId,
|
||||
QQPopenId: user.QqPopenId,
|
||||
|
||||
@ -25,4 +25,5 @@ type Rewards struct {
|
||||
CreatedAt *gtime.Time // 创建时间
|
||||
UpdatedAt *gtime.Time // 更新时间
|
||||
DeletedAt *gtime.Time // 软删除时间戳
|
||||
RemainStock interface{} // 剩余库存数量
|
||||
}
|
||||
|
||||
@ -18,7 +18,6 @@ type Users struct {
|
||||
Nickname interface{} // 昵称
|
||||
Avatar interface{} // 用户头像URL
|
||||
PasswordHash interface{} // 密码哈希
|
||||
Email interface{} // 邮箱地址
|
||||
PhoneNumber interface{} // 手机号
|
||||
WxPopenId interface{} // 微信 PopenID
|
||||
QqPopenId interface{} // QQ PopenID
|
||||
|
||||
@ -23,4 +23,5 @@ type Rewards struct {
|
||||
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` // 创建时间
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"` // 更新时间
|
||||
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:"软删除时间戳"` // 软删除时间戳
|
||||
RemainStock int `json:"remainStock" orm:"remain_stock" description:"剩余库存数量"` // 剩余库存数量
|
||||
}
|
||||
|
||||
@ -16,7 +16,6 @@ type Users struct {
|
||||
Nickname string `json:"nickname" orm:"nickname" description:"昵称"` // 昵称
|
||||
Avatar string `json:"avatar" orm:"avatar" description:"用户头像URL"` // 用户头像URL
|
||||
PasswordHash string `json:"passwordHash" orm:"password_hash" description:"密码哈希"` // 密码哈希
|
||||
Email string `json:"email" orm:"email" description:"邮箱地址"` // 邮箱地址
|
||||
PhoneNumber string `json:"phoneNumber" orm:"phone_number" description:"手机号"` // 手机号
|
||||
WxPopenId string `json:"wxPopenId" orm:"wx_popen_id" description:"微信 PopenID"` // 微信 PopenID
|
||||
QqPopenId string `json:"qqPopenId" orm:"qq_popen_id" description:"QQ PopenID"` // QQ PopenID
|
||||
|
||||
@ -34,10 +34,6 @@ wechat:
|
||||
ticketExpire: 60
|
||||
token: "arenax"
|
||||
|
||||
rsa:
|
||||
publickey: "./manifest/config/public.pem"
|
||||
privatekey: "./manifest/config/private.pem"
|
||||
|
||||
#OSS配置
|
||||
oss:
|
||||
aliyun:
|
||||
@ -47,5 +43,7 @@ oss:
|
||||
endpoint: "oss-us-east-1.aliyuncs.com"
|
||||
|
||||
gamelife:
|
||||
platId: "b1749611654"
|
||||
platId: "quanyou"
|
||||
secret: "LqPQ2gbF"
|
||||
mode: "test"
|
||||
rsaKey: "./manifest/config/全游-测试环境密钥.txt"
|
||||
|
||||
@ -1,28 +0,0 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCHXJazSOFka3q+
|
||||
xyBqVuLtK+OElsgRQyQCRakBvcBkq5lIl1G+6ivuju+q3bemiYzOWah/H/+7848c
|
||||
yu505CpJtRUvPiSaXqhwIAWAHvD1ckLo9xw3eh9uYdmnZx92+d+oKVcjZWz/M6qQ
|
||||
g6GYf8kE0x8zDKw1Xd89y6xzo7DqFNnE9BHSxeFNSAgp+MOBPn7X2mdDOWl6eGLs
|
||||
qXK6BTTFyeS0JaH1t0ra6JyQ5wau3WKpB22G3pK9+u8MQPKjM+JXdIZFA0eT2SeI
|
||||
qbB0xRfU4fOmhn/eXVyNYws1s92hPq1Lu8/QHf6m6QNbmualgaSiEo/ogKGN1urj
|
||||
/ARsTdbpAgMBAAECggEAF2DnakmhHA3wIjkUISmmgd39qq28GjclZfsQCIv0Sa7V
|
||||
h5MS/E1HjylCvZkTmgDRv+X+Uw58xcJ4KjnmW2v43cgXw5QREFRe9RaivJEbftjg
|
||||
M4pSZkaCXTcrN115MrxPY6TYNvXSkHUk9Va2tzcCygGItvFuYL04zFx8CXDxIkx7
|
||||
4NP3F3AGbQ4GACoIUsKNuQ0WIZO6WrxJP0sGH1iz+oxDIlEkEZAYHAKIIna3gaY5
|
||||
YBvOmRScGDO2K05fLxDJUK0x4nxkBRQ1NRu9Ud1Fo4zwUFxiwM4ZUjaLclgIgv8v
|
||||
5h0urZY/j4994YtC4UvheC53UEAqDKjMWXnjH5u4nQKBgQDlwqSk6St7pAW1lpA+
|
||||
0OMKQgdDe+W+O2a0LPjaSevCX3Q9ml/ToRH+tmVUGOr2S301GqSRaPdauXBDvE29
|
||||
HSoD6gCEsT+TocSxyhn0Gg25fMDz3+H7XVOAj+tPg/IWJG8+KxO5gEwucb6Axl3w
|
||||
NQ29l77SKFgMYitq8N1jjt6LMwKBgQCW0hJzx2dgaYmKrxctWOxfibTaCGBEn4+F
|
||||
6YwmfGJg+qZ+FU+aBkwaocutIudHogIAOXp6e4J086a6cUwx/Eex1tvTztVa8A/W
|
||||
8cRmk+DWIIYN4c/wePe3wDluddtRIgh54ukpFsgVsOEEmzp3GAa8fyUA7dVvuJlQ
|
||||
z1torG11cwKBgQCImppzZiKxR0sRtOwcPOvQLIPPDroAyaZ9l4N5nZurnD8rZT52
|
||||
P/zH+T/zqUEBoM5XpXiU79ipOznRPALoXo+ddiJKwmuvZe3hWuzlYhwo3VCHbuQY
|
||||
JFvCQ08/no5vtcfiKZB3qR0iPARs4gP2DkUWJUOSBeSbsD5qPb0TNV2BWwKBgAz+
|
||||
QBS1YxSNQwotl2OSu5pndKsr+Y8v599zhV1zbc5JCbrm/xqX3EqXEcLytNYZAO8g
|
||||
BIs0xMJqkzyQsi3EPDD3/6w5r2vMLrEn1vG3X7FSz/m2MIHZCg5MgyYfBSvyMKS/
|
||||
hbLCga5MtLX+4YSND1eB5KA13SNo1dx+YLOd1zg9AoGAczXhM+n0beuXDhLkiAm3
|
||||
7Av8lJazrpZg2Oh79IrFJANjVyZZeOVaSfNXPumoDXMZvEMjkIaZZ50IzQfpVdLF
|
||||
7J0Y/hFCTsX6b3JdkiluniiEh1a2I3tC3+Qa4sSPqKNdHcBJSmmcBcpzRLL5n2zc
|
||||
bjt4KNf3ZQ3nHvPHnwrd7pg=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
@ -1,9 +0,0 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAh1yWs0jhZGt6vscgalbi
|
||||
7SvjhJbIEUMkAkWpAb3AZKuZSJdRvuor7o7vqt23pomMzlmofx//u/OPHMrudOQq
|
||||
SbUVLz4kml6ocCAFgB7w9XJC6PccN3ofbmHZp2cfdvnfqClXI2Vs/zOqkIOhmH/J
|
||||
BNMfMwysNV3fPcusc6Ow6hTZxPQR0sXhTUgIKfjDgT5+19pnQzlpenhi7KlyugU0
|
||||
xcnktCWh9bdK2uickOcGrt1iqQdtht6SvfrvDEDyozPiV3SGRQNHk9kniKmwdMUX
|
||||
1OHzpoZ/3l1cjWMLNbPdoT6tS7vP0B3+pukDW5rmpYGkohKP6IChjdbq4/wEbE3W
|
||||
6QIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
38
manifest/config/全游-正式环境密钥.txt
Normal file
38
manifest/config/全游-正式环境密钥.txt
Normal file
@ -0,0 +1,38 @@
|
||||
正式环境
|
||||
-----BEGIN rsa public key-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzdNXFM1ny9+gV+zBwmXc
|
||||
f21XKilaFdAfHB8959URJkp27JS2iqBuDVSaXQTGJcI6aHk0Cz1zCt2crZX9Z40X
|
||||
zEhPE8MRLJZfKDgKbg1Gb7c7Dxj7B6+uTbIsGXV+13SE595VL6depxHfgQS425UM
|
||||
isIPP0isdn7wKey3hJ/COPezOp6/bYwROEy+ZHOMoINWG5Lk3bX0e9axLH1/U19G
|
||||
5ZqtnVlIqV90y9SiDPnuKu12EZRJ4Z5QrG0/CgAloO/97YLahOmoKDnk7dUIvN/w
|
||||
A3B80AGP3aXU7cdwrQfXcDXPG2LoyM9MkSrgsBAOQdJsaDHksudEMqEWnDie/TRq
|
||||
ewIDAQAB
|
||||
-----END rsa public key-----
|
||||
|
||||
-----BEGIN rsa private key-----
|
||||
MIIEpQIBAAKCAQEAzdNXFM1ny9+gV+zBwmXcf21XKilaFdAfHB8959URJkp27JS2
|
||||
iqBuDVSaXQTGJcI6aHk0Cz1zCt2crZX9Z40XzEhPE8MRLJZfKDgKbg1Gb7c7Dxj7
|
||||
B6+uTbIsGXV+13SE595VL6depxHfgQS425UMisIPP0isdn7wKey3hJ/COPezOp6/
|
||||
bYwROEy+ZHOMoINWG5Lk3bX0e9axLH1/U19G5ZqtnVlIqV90y9SiDPnuKu12EZRJ
|
||||
4Z5QrG0/CgAloO/97YLahOmoKDnk7dUIvN/wA3B80AGP3aXU7cdwrQfXcDXPG2Lo
|
||||
yM9MkSrgsBAOQdJsaDHksudEMqEWnDie/TRqewIDAQABAoIBAQCRshNHV2stBrxi
|
||||
4OX7LM2bqhN0ddcd77fF2Vuh2tIL79Qk/dQFZzDf4M5wH+v/WHCt+XXcqv/fZiX9
|
||||
PlolTdvVsC3ByGhEzqDHQHwpkN4WQHbe5gj0VOimeQP8dY53BzT5SQm19NzsmJtE
|
||||
ocoVLXm2U04lttTWAF8S3ky95bS/S1qMbCLlB0ChqCWyZBnLkZgWLK4Vglog3H4H
|
||||
cClMcPNm/kJNLleQ8QH+CYs8fAABaOuD9dEXJAC4XiKUhyDythWjux9pccjDXJ2u
|
||||
xIg1t2x+jBrp5uV8MfjxJRAe2sgCj/qcpT9vTbP8yHTshwkVPYBbsd/RlWlo/zXr
|
||||
8WyN89T5AoGBAN949GqfB/GCjRdf4Bhs57tOc5z9GCZTERcOL07ygma9SLAZ13qK
|
||||
706IThTz1vgj3ZpOsIZ3UspZiVpXkmDZekWrKK7UhB+TMWLDRzlySXlxLIC++JUT
|
||||
VG5ugYPNOG2J18qB0o1V/KqUVMr7MBlnxQKTAoHWnImWMZICAC9q2meNAoGBAOvI
|
||||
0whYFM9zvs5ghIgH3K2z56COPf+V6kb/FlhZhaYFu73YtMu2GxAfwin6ZfTHNypx
|
||||
KWM5y0en4lC962VbfQYphtL0/PdEhNucRMOTGbLQnoKPDWL7JaDdG0MCkhKnSZlo
|
||||
okCughG/UNBMHCLDObYLighbkKKMihmidoDH/jQnAoGBALqXYvWXvekwyaAHxLSA
|
||||
Umk6Exy00zJEz5NBm8y+fpVMXOH1Yc8HLNOUyiWCiC7+u2y5YXmVLkKYyi/tyOIn
|
||||
FIoRZNG9zmgS3fyJ8vGLdL/6+F6zlhnbXvcqO+gSNZh4rP6AsY6jimnfmoE1hS7h
|
||||
T0Vb/I7u5BuZleBE3WS6QoyNAoGBAMkd4ovifdW6F833W/SgKCbuJqu3yMBiwpPO
|
||||
b+PqcGp9x3cXCpgcfBcTz814rVDOQIruPWxK1s8HL67JYKlzEUCZWUxF9iSACIc+
|
||||
UxUzOx9gfWRF2xhLuvvsvZ056xkIImo9avCbKY0z0B3sXa91MJvMWe/pEoTkNcPJ
|
||||
5STR8k3PAoGAE334SjfwxpzYG+lcf9Oyli2HbFHO8u6PXhPQ+xgYUh45KeDIWo0Q
|
||||
j0fmiNrmSYs3Ojs1QtUZMNQWaRmR7Xcysa9pcIFatbbwMfafBO+nROaBbo+bhVKN
|
||||
VRN1as06j/dVhfYWuwx8BxJjsskllpfcSi7riA6nLrnxbUNktpK6/gs=
|
||||
-----END rsa private key-----
|
||||
38
manifest/config/全游-测试环境密钥.txt
Normal file
38
manifest/config/全游-测试环境密钥.txt
Normal file
@ -0,0 +1,38 @@
|
||||
测试环境
|
||||
-----BEGIN rsa public key-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAks8Rak/Gt6IuDcjcpKCI
|
||||
NTj04pWozRaZ1Ryy5DpmtwYW9c7AayIqsIGGTcl8/QiaamTThB2pnn8dZ6o8iCXb
|
||||
z9zG8Jq8GqX4nm8bT7/y3zaTgV6oScY7mw4hfZPSUv2lHaLij4whIrYCOi4mW+lh
|
||||
9Ab//0NbJ5XHxRnlYscuOIKs64ss18disWWFwl5IgCVTPsqqlYZgkwYIdE2FpZds
|
||||
rKYLDY1T16Qwvs+H0rlRZ5yKY8Xhj2x+oU8WygSbFPIZ+sONHyfJ4sxjGRdmxohD
|
||||
4roNycwuHqjOZJauw3Mdkl0ibJE0oCL5yAf8D7li2aUP/0NRSfb64dfG6RhDH6HQ
|
||||
QQIDAQAB
|
||||
-----END rsa public key-----
|
||||
|
||||
-----BEGIN rsa private key-----
|
||||
MIIEogIBAAKCAQEAks8Rak/Gt6IuDcjcpKCINTj04pWozRaZ1Ryy5DpmtwYW9c7A
|
||||
ayIqsIGGTcl8/QiaamTThB2pnn8dZ6o8iCXbz9zG8Jq8GqX4nm8bT7/y3zaTgV6o
|
||||
ScY7mw4hfZPSUv2lHaLij4whIrYCOi4mW+lh9Ab//0NbJ5XHxRnlYscuOIKs64ss
|
||||
18disWWFwl5IgCVTPsqqlYZgkwYIdE2FpZdsrKYLDY1T16Qwvs+H0rlRZ5yKY8Xh
|
||||
j2x+oU8WygSbFPIZ+sONHyfJ4sxjGRdmxohD4roNycwuHqjOZJauw3Mdkl0ibJE0
|
||||
oCL5yAf8D7li2aUP/0NRSfb64dfG6RhDH6HQQQIDAQABAoIBAAPOUHJEHS+3iaAb
|
||||
2/R8oOtYTajuHlEqy9QliVG3XeBSzReUQ5LDcP3gbb3oglABABfQA1fCeRo9y2Jb
|
||||
nHQfHyK1Y4brTAMY2GgrEzcvD7nPrWVGMfCvre3oIOAji+lQ4A3zohH8nQNMWqRt
|
||||
e9sYIszzvYE9mshc7q/iavrzlPQsDQhU/yzkW99x95UCw5sqVWXW6ubfIyqphrKC
|
||||
5Ch7ottruBV1y6CThAZE77O2SR4RRwFKdftXXtXltXAtBvBKq9qpOm5GdY0/zDcK
|
||||
v75gmLJ4Pom78/+bOp4vVhpYhkCl5aixv2Lpf1Dlvwvaz1FR+HHAFecELLwT29tC
|
||||
uAi5mQECgYEAwYmGwGGMk97o6rxrQcsobZ44+Hk5FiK8UOmvUlDCWHnJ9GPAkaFH
|
||||
Lw1+VF4ODnUrOWO55sx15SvYNUfaBieh+jGdBV98zeodETeyc+7DbYkQpaGMRuwl
|
||||
sMN9pMix0q73TQET9PVholssiT4wUAL5Uy+h04nzUbNzOxLCB93DnhECgYEAwjC9
|
||||
1JinezngDFXoFaJ2ta+W25QViNlbJCyBxbuf/UmGbZOrJQAZHIunZHqMGNrgp9ro
|
||||
+z5QhuKfg1pRSdeGC2TwH0D3GiaWsIeYqb7bIFKWuMXIm3klNdNuR1pXIDiB9sfx
|
||||
jx//1ol5+BO0SrhXZNua6euy74JhiupKSJnEnzECgYBdYsXhuHBDvdC3y5kZkzT7
|
||||
x9gHlT7FfpdNl6TgXFWaqZGYWjXGT4LwolstzICN212zAHrocgoFPeXCt9vtElyn
|
||||
RB9XQ18OYQQLlcuHA1PLW9LriQsOAc6h/4J1691aItDzmCyQC4ND+yh/RMG9KeIy
|
||||
kI5Oa4c8ChH1FDUJ5KkKcQKBgHLbd3xGalFFUxKYwTQCquodmEH53Z7ayMClnoBA
|
||||
0Il0spEfVYwF+dRbeb/BiBmvZE+D+GeaXPDbG/QKOKhPVNZqdmhV+ZG7H0f8e7xy
|
||||
yZLdpo5VVak3x12F1+VWNtA0/BHmAydfiufu2nhz1yCW1gIurfsL0QM+/8i1eQhm
|
||||
AtkRAoGAE9moiNCqQPbDVf9LcChzbsgnXsFbwGpzZtw83C8Xf3aKwPWyVXhHS3Sh
|
||||
xaJu7uZTmwwzXYTfpyraKdYDJNCTupaZqZlj28xqxDN2fYoSwPpuMM0uyKDmZwBk
|
||||
IX8kptaMRGorPadI+7UEPfgIjtqYXYeJbChscepcqeu87GjSS1o=
|
||||
-----END rsa private key-----
|
||||
@ -88,14 +88,15 @@ func (s *gamelifeClient) GetUserKeyIV(ctx context.Context, popenId string) (cach
|
||||
// base64编码
|
||||
base64Encode := encrypt.Base64Encode(key)
|
||||
// 向游戏人生发送请求
|
||||
result := struct {
|
||||
secret string `json:"secret"`
|
||||
key string `json:"key"` // 该用户的token,后续的账号绑定、登录态携带都需要此参数。
|
||||
}{}
|
||||
type httpResult struct {
|
||||
Secret string `json:"secret"`
|
||||
Key string `json:"key"` // 该用户的token,后续的账号绑定、登录态携带都需要此参数。
|
||||
}
|
||||
var result httpResult
|
||||
resp, err := resty.New().R().SetBody(map[string]string{
|
||||
"plat_id": s.PlatId,
|
||||
"key": base64Encode,
|
||||
}).SetResult(result).Post(s.keyivUrlMap[s.Mode])
|
||||
}).SetResult(&result).Post(s.keyivUrlMap[s.Mode])
|
||||
if err != nil {
|
||||
err = ecode.Fail.Sub("获取用户信息失败")
|
||||
return
|
||||
@ -107,7 +108,7 @@ func (s *gamelifeClient) GetUserKeyIV(ctx context.Context, popenId string) (cach
|
||||
|
||||
}
|
||||
|
||||
decode, err := encrypt.Base64Decode(result.secret)
|
||||
decode, err := encrypt.Base64Decode(result.Secret)
|
||||
if err != nil {
|
||||
err = ecode.Fail.Sub("解密用户信息失败")
|
||||
return
|
||||
@ -121,15 +122,15 @@ func (s *gamelifeClient) GetUserKeyIV(ctx context.Context, popenId string) (cach
|
||||
|
||||
}
|
||||
aesResult := struct {
|
||||
key string `json:"key"`
|
||||
iv string `json:"iv"`
|
||||
Key string `json:"key"`
|
||||
IV string `json:"iv"`
|
||||
}{}
|
||||
if err = json.Unmarshal(plain, &aesResult); err != nil {
|
||||
err = ecode.Fail.Sub("解密用户信息失败")
|
||||
return
|
||||
}
|
||||
|
||||
gamelifeCache := model.UserGamelifeCache{Aes: aesResult.key, IV: aesResult.iv, Token: result.key}
|
||||
gamelifeCache := model.UserGamelifeCache{Aes: aesResult.Key, IV: aesResult.IV, Token: result.Key}
|
||||
// 将用户的 aeskey 和 iv 存储到缓存当中,用于后续请求数据加密, 固定时间 2 小时同时不同用户加上一个随机时间
|
||||
if err = g.Redis().SetEX(ctx, fmt.Sprintf(consts.GameLifeUserKey, popenId), gamelifeCache, int64(consts.GameLifeUserExpire+grand.Intn(1000))); err != nil {
|
||||
err = ecode.Fail.Sub("设置用户信息失败")
|
||||
|
||||
@ -7,10 +7,11 @@ import (
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type rsaClient struct {
|
||||
@ -28,7 +29,7 @@ func init() {
|
||||
ctx := context.Background()
|
||||
once.Do(func() {
|
||||
instance = &rsaClient{}
|
||||
err := instance.loadKeys(g.Config().MustGet(ctx, "rsa.publickey").String(), g.Config().MustGet(ctx, "rsa.privatekey").String())
|
||||
err := instance.loadKeys(g.Config().MustGet(ctx, "gamelife.rsaKey").String())
|
||||
if err != nil {
|
||||
panic("加载 RSA 密钥失败: " + err.Error())
|
||||
}
|
||||
@ -80,47 +81,94 @@ func (c *rsaClient) DecryptWithRsaPrivateKey(cipher []byte) ([]byte, error) {
|
||||
//
|
||||
// 返回值:
|
||||
// - 成功返回 nil,否则返回错误信息。
|
||||
func (c *rsaClient) loadKeys(publicKeyPath, privateKeyPath string) error {
|
||||
// 加载公钥
|
||||
pubBytes, err := os.ReadFile(publicKeyPath)
|
||||
func (c *rsaClient) loadKeys(keyFilePath string) error {
|
||||
// 读取密钥文件
|
||||
keyBytes, err := os.ReadFile(keyFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pubBlock, _ := pem.Decode(pubBytes)
|
||||
if pubBlock == nil {
|
||||
return errors.New("无法解析公钥 PEM 文件")
|
||||
}
|
||||
pubKey, err := x509.ParsePKIXPublicKey(pubBlock.Bytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var ok bool
|
||||
if c.publicKey, ok = pubKey.(*rsa.PublicKey); !ok {
|
||||
return errors.New("公钥不是 RSA 公钥")
|
||||
return fmt.Errorf("读取密钥文件失败: %w", err)
|
||||
}
|
||||
|
||||
// 加载私钥
|
||||
privBytes, err := os.ReadFile(privateKeyPath)
|
||||
var pubFound, privFound bool
|
||||
rest := keyBytes
|
||||
|
||||
for {
|
||||
var block *pem.Block
|
||||
block, rest = pem.Decode(rest)
|
||||
if block == nil {
|
||||
break
|
||||
}
|
||||
|
||||
// 转换为小写以匹配你的密钥格式
|
||||
blockTypeLower := strings.ToLower(block.Type)
|
||||
|
||||
switch blockTypeLower {
|
||||
case "rsa public key":
|
||||
// 尝试解析 PKCS#1 格式的公钥
|
||||
pubKey, err := x509.ParsePKCS1PublicKey(block.Bytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
privBlock, _ := pem.Decode(privBytes)
|
||||
if privBlock == nil {
|
||||
return errors.New("无法解析私钥 PEM 文件")
|
||||
}
|
||||
// 尝试解析 PKCS#8 格式
|
||||
privKey, err := x509.ParsePKCS8PrivateKey(privBlock.Bytes)
|
||||
// 尝试 PKIX 格式(兼容性处理)
|
||||
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
|
||||
if err != nil {
|
||||
// 回退尝试 PKCS#1 格式
|
||||
privKey, err = x509.ParsePKCS1PrivateKey(privBlock.Bytes)
|
||||
return fmt.Errorf("无法解析 RSA 公钥: %w", err)
|
||||
}
|
||||
var ok bool
|
||||
if c.publicKey, ok = pub.(*rsa.PublicKey); !ok {
|
||||
return errors.New("解析的公钥不是 RSA 公钥")
|
||||
}
|
||||
} else {
|
||||
c.publicKey = pubKey
|
||||
}
|
||||
pubFound = true
|
||||
|
||||
case "rsa private key":
|
||||
// 解析 PKCS#1 格式的私钥
|
||||
privKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
return errors.New("解析私钥失败: 既不是 PKCS#8 也不是 PKCS#1 格式")
|
||||
return fmt.Errorf("无法解析 RSA 私钥: %w", err)
|
||||
}
|
||||
c.privateKey = privKey
|
||||
privFound = true
|
||||
|
||||
default:
|
||||
// 忽略未知的 PEM 块
|
||||
continue
|
||||
}
|
||||
}
|
||||
var ok2 bool
|
||||
if c.privateKey, ok2 = privKey.(*rsa.PrivateKey); !ok2 {
|
||||
return errors.New("私钥不是 RSA 私钥")
|
||||
|
||||
if !pubFound {
|
||||
return errors.New("未找到有效的 RSA 公钥")
|
||||
}
|
||||
if !privFound {
|
||||
return errors.New("未找到有效的 RSA 私钥")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// EncryptWithPublicKey 使用公钥加密数据
|
||||
func (c *rsaClient) EncryptWithPublicKey(plaintext []byte) ([]byte, error) {
|
||||
if c.publicKey == nil {
|
||||
return nil, errors.New("公钥未加载")
|
||||
}
|
||||
|
||||
// 使用 OAEP 填充进行加密
|
||||
ciphertext, err := rsa.EncryptPKCS1v15(rand.Reader, c.publicKey, plaintext)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("公钥加密失败: %w", err)
|
||||
}
|
||||
return ciphertext, nil
|
||||
}
|
||||
|
||||
// DecryptWithPrivateKey 使用私钥解密数据
|
||||
func (c *rsaClient) DecryptWithPrivateKey(ciphertext []byte) ([]byte, error) {
|
||||
if c.privateKey == nil {
|
||||
return nil, errors.New("私钥未加载")
|
||||
}
|
||||
|
||||
// 使用 OAEP 填充进行解密
|
||||
plaintext, err := rsa.DecryptPKCS1v15(rand.Reader, c.privateKey, ciphertext)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("私钥解密失败: %w", err)
|
||||
}
|
||||
return plaintext, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user