修复登录失效后跳转,发送邮件逻辑

This commit is contained in:
xmdhs 2023-11-23 22:09:33 +08:00
parent 500d2cc223
commit ed4725e179
No known key found for this signature in database
GPG Key ID: E809D6D43DEFCC95
7 changed files with 157 additions and 10 deletions

View File

@ -35,6 +35,7 @@ import SecurityIcon from '@mui/icons-material/Security';
import SettingsIcon from '@mui/icons-material/Settings';
import { Link } from "react-router-dom";
import GroupIcon from '@mui/icons-material/Group';
import { ApiErr } from '@/apis/error';
const drawerWidth = 240;
const DrawerOpen = atom(false)
@ -211,12 +212,16 @@ const MyDrawer = function MyDrawer() {
const theme = useTheme();
const isLg = useMediaQuery(theme.breakpoints.up('lg'))
const [open, setOpen] = useAtom(DrawerOpen)
const navigate = useNavigate();
const userinfo = useRequest(() => userInfo(nowToken), {
refreshDeps: [nowToken],
cacheKey: "/api/v1/user" + nowToken,
staleTime: 60000,
onError: e => {
if (e instanceof ApiErr && e.code == 5) {
navigate("/login")
}
console.warn(e)
setErr(String(e))
},

1
go.mod
View File

@ -38,6 +38,7 @@ require (
github.com/leodido/go-urn v1.2.4 // indirect
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/wneessen/go-mail v0.4.0 // indirect
github.com/zclconf/go-cty v1.8.0 // indirect
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect
golang.org/x/mod v0.10.0 // indirect

2
go.sum
View File

@ -97,6 +97,8 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
github.com/wneessen/go-mail v0.4.0 h1:Oo4HLIV8My7G9JuZkoOX6eipXQD+ACvIqURYeIzUc88=
github.com/wneessen/go-mail v0.4.0/go.mod h1:zxOlafWCP/r6FEhAaRgH4IC1vg2YXxO0Nar9u0IScZ8=
github.com/zclconf/go-cty v1.8.0 h1:s4AvqaeQzJIu3ndv4gVIhplVD0krU+bgrcLSVUnaWuA=
github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=

9
handle/email.go Normal file
View File

@ -0,0 +1,9 @@
package handle
import "net/http"
func (h *Handel) SendVerifyCode() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
}
}

View File

@ -15,21 +15,25 @@ import (
"github.com/xmdhs/authlib-skin/config"
"github.com/xmdhs/authlib-skin/model"
"github.com/xmdhs/authlib-skin/service"
"github.com/xmdhs/authlib-skin/service/email"
)
type Handel struct {
webService *service.WebService
validate *validator.Validate
emailService *email.Email
config config.Config
logger *slog.Logger
}
func NewHandel(webService *service.WebService, validate *validator.Validate, config config.Config, logger *slog.Logger) *Handel {
func NewHandel(webService *service.WebService, validate *validator.Validate,
config config.Config, logger *slog.Logger, email *email.Email) *Handel {
return &Handel{
webService: webService,
validate: validate,
config: config,
logger: logger,
emailService: email,
}
}

View File

@ -12,12 +12,13 @@ import (
"github.com/xmdhs/authlib-skin/handle/yggdrasil"
"github.com/xmdhs/authlib-skin/server/route"
"github.com/xmdhs/authlib-skin/service"
"github.com/xmdhs/authlib-skin/service/email"
yggdrasilS "github.com/xmdhs/authlib-skin/service/yggdrasil"
)
func InitializeRoute(ctx context.Context, c config.Config) (*http.Server, func(), error) {
panic(wire.Build(Set, route.NewRoute, NewSlog,
NewServer, handle.NewHandel, yggdrasil.NewYggdrasil,
service.NewWebService, yggdrasilS.NewYggdrasil,
service.NewWebService, yggdrasilS.NewYggdrasil, email.NewEmail,
))
}

125
service/email/email.go Normal file
View File

@ -0,0 +1,125 @@
package email
import (
"context"
"crypto/rsa"
"errors"
"fmt"
"math/rand"
"time"
"github.com/samber/lo"
"github.com/wneessen/go-mail"
"github.com/xmdhs/authlib-skin/config"
"github.com/xmdhs/authlib-skin/db/cache"
)
type EmailConfig struct {
Host string
Port int
SSL bool
Name string
Pass string
}
type Email struct {
emailConfig []EmailConfig
pri *rsa.PrivateKey
config config.Config
cache cache.Cache
}
func NewEmail(emailConfig []EmailConfig, pri *rsa.PrivateKey, config config.Config, cache cache.Cache) Email {
return Email{
emailConfig: emailConfig,
pri: pri,
config: config,
cache: cache,
}
}
func (e Email) getRandEmailUser() EmailConfig {
i := rand.Intn(len(e.emailConfig))
return e.emailConfig[i]
}
func (e Email) SendEmail(ctx context.Context, to string, subject, body string) error {
u := e.getRandEmailUser()
m := mail.NewMsg()
err := m.From(u.Name)
if err != nil {
return fmt.Errorf("SendRegVerify: %w", err)
}
err = m.To(to)
if err != nil {
return fmt.Errorf("SendRegVerify: %w", err)
}
m.Subject(subject)
m.SetBodyString(mail.TypeTextHTML, body)
c, err := mail.NewClient(u.Host, mail.WithPort(u.Port), mail.WithSMTPAuth(mail.SMTPAuthPlain),
mail.WithUsername(u.Name), mail.WithPassword(u.Pass))
if err != nil {
return fmt.Errorf("SendRegVerify: %w", err)
}
if u.SSL {
c.SetSSL(true)
}
defer c.Close()
err = c.DialAndSendWithContext(ctx, m)
if err != nil {
return fmt.Errorf("SendRegVerify: %w", err)
}
return nil
}
func (e Email) SendVerifyCode(ctx context.Context, email string, interval int) error {
sendKey := []byte("SendEmail" + email)
sendB, err := e.cache.Get(sendKey)
if err != nil {
return fmt.Errorf("SendRegVerifyCode: %w", err)
}
if sendB == nil {
return fmt.Errorf("SendRegVerifyCode: %w", ErrSendLimit)
}
err = e.cache.Put(sendKey, []byte{1}, time.Now().Add(time.Second*time.Duration(interval)))
if err != nil {
return fmt.Errorf("SendRegVerifyCode: %w", err)
}
code := lo.RandomString(8, append(lo.NumbersCharset, lo.UpperCaseLettersCharset...))
err = e.cache.Put([]byte("VerifyCode"+email), []byte(code), time.Now().Add(5*time.Minute))
if err != nil {
return fmt.Errorf("SendRegVerifyCode: %w", err)
}
err = e.SendEmail(ctx, email, "验证你的邮箱", fmt.Sprintf("验证码:%v五分钟内有效", code))
if err != nil {
return fmt.Errorf("SendRegVerifyCode: %w", err)
}
return nil
}
var (
ErrCodeNotValid = errors.New("验证码无效")
ErrSendLimit = errors.New("邮件发送限制")
)
func (e Email) VerifyCode(email, code string) error {
key := []byte("VerifyCode" + email)
codeb, err := e.cache.Get(key)
if err != nil {
return fmt.Errorf("VerifyCode: %w", err)
}
if string(codeb) != code {
err := e.cache.Del(key)
if err != nil {
return fmt.Errorf("VerifyCode: %w", err)
}
return ErrCodeNotValid
}
return nil
}