修复登录失效后跳转,发送邮件逻辑
This commit is contained in:
parent
500d2cc223
commit
ed4725e179
@ -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
1
go.mod
@ -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
2
go.sum
@ -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
9
handle/email.go
Normal file
@ -0,0 +1,9 @@
|
||||
package handle
|
||||
|
||||
import "net/http"
|
||||
|
||||
func (h *Handel) SendVerifyCode() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
}
|
||||
}
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
125
service/email/email.go
Normal 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
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user