重构远程接口,替换为Baiyin SDK & 添加实名认证处理逻辑
This commit is contained in:
199
web/handlers/iden.go
Normal file
199
web/handlers/iden.go
Normal file
@@ -0,0 +1,199 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"platform/pkg/env"
|
||||
"platform/pkg/rds"
|
||||
"platform/pkg/u"
|
||||
"platform/web/auth"
|
||||
m "platform/web/models"
|
||||
q "platform/web/queries"
|
||||
"platform/web/services"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
jdc "github.com/jdcloud-api/jdcloud-sdk-go/core"
|
||||
"github.com/jdcloud-api/jdcloud-sdk-go/services/cloudauth/apis"
|
||||
jdclient "github.com/jdcloud-api/jdcloud-sdk-go/services/cloudauth/client"
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
// region Identify
|
||||
|
||||
type IdentifyReq struct {
|
||||
Type int32 `json:"type" validate:"required,oneof=1 2"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
IdenNo string `json:"iden_no" validate:"required"`
|
||||
}
|
||||
|
||||
type IdentifyRes struct {
|
||||
Identified bool `json:"identified"`
|
||||
Target string `json:"target"`
|
||||
}
|
||||
|
||||
func Identify(c *fiber.Ctx) error {
|
||||
|
||||
// 检查权限
|
||||
authCtx, err := auth.Protect(c, []services.PayloadType{services.PayloadUser}, []string{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
user, err := q.User.
|
||||
Where(q.User.ID.Eq(authCtx.Payload.Id)).
|
||||
Select(q.User.ID, q.User.IDToken).
|
||||
Take()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if user.IDToken != "" {
|
||||
// 用户已实名认证
|
||||
return c.JSON(IdentifyRes{
|
||||
Identified: true,
|
||||
})
|
||||
}
|
||||
|
||||
// 解析请求参数
|
||||
req := new(IdentifyReq)
|
||||
if err := c.BodyParser(req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 请求活体认证
|
||||
var id = services.ID.GenReadable("iden")
|
||||
|
||||
var credential = jdc.NewCredentials(env.IdenAccessKey, env.IdenSecretKey)
|
||||
var client = jdclient.NewCloudauthClient(credential)
|
||||
resp, err := client.GetAliveUrl(apis.NewGetAliveUrlRequestWithAllParams(
|
||||
u.P(req.Name),
|
||||
u.P(req.IdenNo),
|
||||
env.IdenCallbackUrl+"?id="+id,
|
||||
))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 保存认证中间状态
|
||||
info := idenInfo{
|
||||
Uid: authCtx.Payload.Id,
|
||||
Type: req.Type,
|
||||
Name: req.Name,
|
||||
IdNo: req.IdenNo,
|
||||
Token: resp.Result.Token,
|
||||
}
|
||||
infoStr, err := json.Marshal(info)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = rds.Client.Set(c.Context(), idenKey(id), infoStr, 30*time.Minute).Err()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(IdentifyRes{
|
||||
Identified: false,
|
||||
Target: resp.Result.Url,
|
||||
})
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region IdentifyCallback
|
||||
|
||||
type IdentifyCallbackReq struct {
|
||||
Id string `json:"id" validate:"required"`
|
||||
}
|
||||
|
||||
type IdentifyCallbackRes struct {
|
||||
Success bool `json:"success"`
|
||||
Message string `json:"desc"`
|
||||
}
|
||||
|
||||
func IdentifyCallback(c *fiber.Ctx) error {
|
||||
|
||||
// 解析请求参数
|
||||
req := new(IdentifyCallbackReq)
|
||||
if err := c.BodyParser(req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 获取 token
|
||||
infoStr, err := rds.Client.GetDel(c.Context(), idenKey(req.Id)).Result()
|
||||
if err != nil {
|
||||
if errors.Is(err, redis.Nil) {
|
||||
return c.JSON(IdentifyCallbackRes{
|
||||
Success: false,
|
||||
Message: "认证已过期",
|
||||
})
|
||||
}
|
||||
return err
|
||||
}
|
||||
info := idenInfo{}
|
||||
err = json.Unmarshal([]byte(infoStr), &info)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 获取认证结果
|
||||
var credential = jdc.NewCredentials(env.IdenAccessKey, env.IdenSecretKey)
|
||||
var client = jdclient.NewCloudauthClient(credential)
|
||||
resp, err := client.GetAliveResult(apis.NewGetAliveResultRequestWithAllParams(
|
||||
info.Token,
|
||||
))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if resp.Error.Code != 0 {
|
||||
return c.JSON(IdentifyCallbackRes{
|
||||
Success: false,
|
||||
Message: resp.Error.Message,
|
||||
})
|
||||
}
|
||||
|
||||
if resp.Result.H5Result != "ok" || resp.Result.SmResult != "ok" || resp.Result.RxResult != "ok" {
|
||||
return c.JSON(IdentifyCallbackRes{
|
||||
Success: false,
|
||||
Message: resp.Result.Desc,
|
||||
})
|
||||
}
|
||||
|
||||
// 更新用户实名认证状态
|
||||
_, err = q.User.Debug().
|
||||
Where(q.User.ID.Eq(info.Uid)).
|
||||
Select(
|
||||
q.User.IDType,
|
||||
q.User.IDNo,
|
||||
q.User.IDToken,
|
||||
q.User.Name,
|
||||
).
|
||||
Updates(m.User{
|
||||
IDType: info.Type,
|
||||
IDNo: info.IdNo,
|
||||
IDToken: info.Token,
|
||||
Name: info.Name,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(IdentifyCallbackRes{
|
||||
Success: true,
|
||||
Message: resp.Result.Desc,
|
||||
})
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
func idenKey(id string) string {
|
||||
return fmt.Sprintf("iden:%s", id)
|
||||
}
|
||||
|
||||
type idenInfo struct {
|
||||
Uid int32 `json:"uid"`
|
||||
Type int32 `json:"type"`
|
||||
Name string `json:"name"`
|
||||
IdNo string `json:"id_no"`
|
||||
Token string `json:"token"`
|
||||
}
|
||||
@@ -66,8 +66,8 @@ func loginByPhone(c *fiber.Ctx, req *LoginReq) error {
|
||||
// 如果用户不存在,初始化用户 todo 保存默认权限信息
|
||||
if user == nil {
|
||||
user = &models.User{
|
||||
Phone: req.Username,
|
||||
Name: req.Username,
|
||||
Phone: req.Username,
|
||||
Username: req.Username,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user