web 使用专用登录接口
This commit is contained in:
parent
63808f0a14
commit
74fd0902ac
23
cmd/authlibskin/main.go
Normal file
23
cmd/authlibskin/main.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"flag"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/xmdhs/authlib-skin/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
var configPath string
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
flag.StringVar(&configPath, "c", "", "")
|
||||||
|
flag.Parse()
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ctx := context.Background()
|
||||||
|
os.ReadFile(configPath)
|
||||||
|
|
||||||
|
config.YamlDeCode()
|
||||||
|
}
|
16
config/yaml.go
Normal file
16
config/yaml.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func YamlDeCode(b []byte) (Config, error) {
|
||||||
|
var c Config
|
||||||
|
err := yaml.Unmarshal(b, &c)
|
||||||
|
if err != nil {
|
||||||
|
return c, fmt.Errorf("YamlDeCode: %w", err)
|
||||||
|
}
|
||||||
|
return c, nil
|
||||||
|
}
|
@ -1,24 +1,21 @@
|
|||||||
import type { tokenData, ApiUser, ApiServerInfo, YggProfile, ApiConfig, List, UserInfo, EditUser } from '@/apis/model'
|
import type { tokenData, ApiUser, ApiServerInfo, YggProfile, ApiConfig, List, UserInfo, EditUser } from '@/apis/model'
|
||||||
import { apiGet } from '@/apis/utils'
|
import { apiGet } from '@/apis/utils'
|
||||||
|
|
||||||
export async function login(username: string, password: string) {
|
export async function login(email: string, password: string, captchaToken: string) {
|
||||||
const v = await fetch(import.meta.env.VITE_APIADDR + "/api/yggdrasil/authserver/authenticate", {
|
const v = await fetch(import.meta.env.VITE_APIADDR + "/api/v1/user/login", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
"username": username,
|
"email": email,
|
||||||
"password": password,
|
"password": password,
|
||||||
|
"CaptchaToken": captchaToken
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
const data = await v.json()
|
return await apiGet<tokenData>(v)
|
||||||
if (!v.ok) {
|
|
||||||
throw new Error(data?.errorMessage)
|
|
||||||
}
|
|
||||||
return data as tokenData
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function register(email: string, username: string, password: string, captchaToken: string) {
|
export async function register(email: string, username: string, password: string, captchaToken: string) {
|
||||||
const v = await fetch(import.meta.env.VITE_APIADDR + "/api/v1/user/reg", {
|
const v = await fetch(import.meta.env.VITE_APIADDR + "/api/v1/user/reg", {
|
||||||
method: "PUT",
|
method: "POST",
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
"Email": email,
|
"Email": email,
|
||||||
"Password": password,
|
"Password": password,
|
||||||
@ -119,7 +116,7 @@ export async function ListUser(page: number, token: string, email: string, name:
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function editUser(u: EditUser, token: string, uid: string) {
|
export async function editUser(u: EditUser, token: string, uid: string) {
|
||||||
const r = await fetch(import.meta.env.VITE_APIADDR + "/api/v1/admin/user/" + uid,{
|
const r = await fetch(import.meta.env.VITE_APIADDR + "/api/v1/admin/user/" + uid, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Authorization": "Bearer " + token
|
"Authorization": "Bearer " + token
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
export interface tokenData {
|
export interface tokenData {
|
||||||
accessToken: string
|
token: string
|
||||||
selectedProfile: {
|
name: string
|
||||||
name: string
|
uuid: string
|
||||||
id: string
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Api<T> {
|
export interface Api<T> {
|
||||||
|
@ -18,6 +18,9 @@ import { Link as RouterLink, useNavigate } from "react-router-dom";
|
|||||||
import Loading from '@/components/Loading'
|
import Loading from '@/components/Loading'
|
||||||
import CheckInput, { refType } from '@/components/CheckInput'
|
import CheckInput, { refType } from '@/components/CheckInput'
|
||||||
import useTitle from '@/hooks/useTitle';
|
import useTitle from '@/hooks/useTitle';
|
||||||
|
import CaptchaWidget from '@/components/CaptchaWidget';
|
||||||
|
import type { refType as CaptchaWidgetRef } from '@/components/CaptchaWidget'
|
||||||
|
import { ApiErr } from '@/apis/error';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -29,6 +32,8 @@ export default function SignIn() {
|
|||||||
const checkList = React.useRef<Map<string, refType>>(new Map<string, refType>())
|
const checkList = React.useRef<Map<string, refType>>(new Map<string, refType>())
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
useTitle("登录")
|
useTitle("登录")
|
||||||
|
const captchaRef = React.useRef<CaptchaWidgetRef>(null)
|
||||||
|
const [captchaToken, setCaptchaToken] = useState("");
|
||||||
|
|
||||||
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
|
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@ -44,17 +49,33 @@ export default function SignIn() {
|
|||||||
|
|
||||||
if (loading) return
|
if (loading) return
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
login(postData.email!, postData.password ?? "").
|
login(postData.email!, postData.password ?? "", captchaToken).
|
||||||
then(v => {
|
then(v => {
|
||||||
if (!v) return
|
if (!v) return
|
||||||
setToken(v.accessToken)
|
setToken(v.token)
|
||||||
setUserInfo({
|
setUserInfo({
|
||||||
uuid: v.selectedProfile.id,
|
uuid: v.uuid,
|
||||||
name: v.selectedProfile.name,
|
name: v.name,
|
||||||
})
|
})
|
||||||
navigate("/profile")
|
navigate("/profile")
|
||||||
}).
|
}).
|
||||||
catch(v => [setErr(String(v)), console.warn(v)]).
|
catch(v => {
|
||||||
|
captchaRef.current?.reload()
|
||||||
|
|
||||||
|
if (v instanceof ApiErr) {
|
||||||
|
switch (v.code) {
|
||||||
|
case 6:
|
||||||
|
setErr("错误的密码")
|
||||||
|
break
|
||||||
|
case 9:
|
||||||
|
setErr("用户已被禁用")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setErr(String(v))
|
||||||
|
console.warn(v)
|
||||||
|
}).
|
||||||
finally(() => setLoading(false))
|
finally(() => setLoading(false))
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -104,6 +125,7 @@ export default function SignIn() {
|
|||||||
id="password"
|
id="password"
|
||||||
autoComplete="current-password"
|
autoComplete="current-password"
|
||||||
/>
|
/>
|
||||||
|
<CaptchaWidget ref={captchaRef} onSuccess={setCaptchaToken} />
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
fullWidth
|
fullWidth
|
||||||
|
1
go.mod
1
go.mod
@ -15,6 +15,7 @@ require (
|
|||||||
github.com/google/wire v0.5.0
|
github.com/google/wire v0.5.0
|
||||||
github.com/samber/lo v1.38.1
|
github.com/samber/lo v1.38.1
|
||||||
golang.org/x/crypto v0.7.0
|
golang.org/x/crypto v0.7.0
|
||||||
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
1
go.sum
1
go.sum
@ -116,6 +116,7 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1N
|
|||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
@ -2,15 +2,12 @@ package handle
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/xmdhs/authlib-skin/model"
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
"github.com/xmdhs/authlib-skin/service"
|
|
||||||
"github.com/xmdhs/authlib-skin/service/utils"
|
|
||||||
|
|
||||||
U "github.com/xmdhs/authlib-skin/utils"
|
U "github.com/xmdhs/authlib-skin/utils"
|
||||||
)
|
)
|
||||||
@ -28,11 +25,7 @@ func (h *Handel) NeedAuth(handle http.Handler) http.Handler {
|
|||||||
}
|
}
|
||||||
t, err := h.webService.Auth(ctx, token)
|
t, err := h.webService.Auth(ctx, token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, utils.ErrTokenInvalid) {
|
h.handleErrorService(ctx, w, err)
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrAuth, 401, slog.LevelDebug)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrService, 500, slog.LevelWarn)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r = r.WithContext(context.WithValue(ctx, tokenKey, t))
|
r = r.WithContext(context.WithValue(ctx, tokenKey, t))
|
||||||
@ -46,11 +39,7 @@ func (h *Handel) NeedAdmin(handle http.Handler) http.Handler {
|
|||||||
t := ctx.Value(tokenKey).(*model.TokenClaims)
|
t := ctx.Value(tokenKey).(*model.TokenClaims)
|
||||||
err := h.webService.IsAdmin(ctx, t)
|
err := h.webService.IsAdmin(ctx, t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, service.ErrNotAdmin) {
|
h.handleErrorService(ctx, w, err)
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrNotAdmin, 401, slog.LevelDebug)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrService, 500, slog.LevelWarn)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
handle.ServeHTTP(w, r)
|
handle.ServeHTTP(w, r)
|
||||||
@ -78,7 +67,7 @@ func (h *Handel) ListUser() http.HandlerFunc {
|
|||||||
|
|
||||||
ul, uc, err := h.webService.ListUser(ctx, pagei, email, name)
|
ul, uc, err := h.webService.ListUser(ctx, pagei, email, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrService, 500, slog.LevelWarn)
|
h.handleErrorService(ctx, w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
encodeJson(w, model.API[model.List[model.UserList]]{Data: model.List[model.UserList]{List: ul, Total: uc}})
|
encodeJson(w, model.API[model.List[model.UserList]]{Data: model.List[model.UserList]{List: ul, Total: uc}})
|
||||||
@ -106,7 +95,7 @@ func (h *Handel) EditUser() http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
err = h.webService.EditUser(ctx, a, uidi)
|
err = h.webService.EditUser(ctx, a, uidi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrService, 500, slog.LevelWarn)
|
h.handleErrorService(ctx, w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
encodeJson[any](w, model.API[any]{
|
encodeJson[any](w, model.API[any]{
|
||||||
|
@ -3,12 +3,53 @@ package handle
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/xmdhs/authlib-skin/model"
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
|
"github.com/xmdhs/authlib-skin/service"
|
||||||
|
"github.com/xmdhs/authlib-skin/service/utils"
|
||||||
|
sutils "github.com/xmdhs/authlib-skin/service/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (h *Handel) handleErrorService(ctx context.Context, w http.ResponseWriter, err error) {
|
||||||
|
if errors.Is(err, service.ErrExistUser) {
|
||||||
|
h.handleError(ctx, w, err.Error(), model.ErrExistUser, 400, slog.LevelDebug)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if errors.Is(err, service.ErrExitsName) {
|
||||||
|
h.handleError(ctx, w, err.Error(), model.ErrExitsName, 400, slog.LevelDebug)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if errors.Is(err, service.ErrRegLimit) {
|
||||||
|
h.handleError(ctx, w, err.Error(), model.ErrRegLimit, 400, slog.LevelDebug)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if errors.Is(err, service.ErrCaptcha) {
|
||||||
|
h.handleError(ctx, w, err.Error(), model.ErrCaptcha, 400, slog.LevelDebug)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if errors.Is(err, service.ErrPassWord) {
|
||||||
|
h.handleError(ctx, w, err.Error(), model.ErrPassWord, 401, slog.LevelDebug)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if errors.Is(err, sutils.ErrUserDisable) {
|
||||||
|
h.handleError(ctx, w, err.Error(), model.ErrUserDisable, 401, slog.LevelDebug)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if errors.Is(err, service.ErrNotAdmin) {
|
||||||
|
h.handleError(ctx, w, err.Error(), model.ErrNotAdmin, 401, slog.LevelDebug)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if errors.Is(err, utils.ErrTokenInvalid) {
|
||||||
|
h.handleError(ctx, w, err.Error(), model.ErrAuth, 401, slog.LevelDebug)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
h.handleError(ctx, w, err.Error(), model.ErrService, 500, slog.LevelWarn)
|
||||||
|
}
|
||||||
|
|
||||||
func (h *Handel) handleError(ctx context.Context, w http.ResponseWriter, msg string, code model.APIStatus, httpcode int, level slog.Level) {
|
func (h *Handel) handleError(ctx context.Context, w http.ResponseWriter, msg string, code model.APIStatus, httpcode int, level slog.Level) {
|
||||||
h.logger.Log(ctx, level, msg)
|
h.logger.Log(ctx, level, msg)
|
||||||
w.WriteHeader(httpcode)
|
w.WriteHeader(httpcode)
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
package handle
|
package handle
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/xmdhs/authlib-skin/model"
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
"github.com/xmdhs/authlib-skin/service"
|
|
||||||
"github.com/xmdhs/authlib-skin/utils"
|
"github.com/xmdhs/authlib-skin/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -20,7 +18,7 @@ func (h *Handel) Reg() http.HandlerFunc {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
u, err := utils.DeCodeBody[model.User](r.Body, h.validate)
|
u, err := utils.DeCodeBody[model.UserReg](r.Body, h.validate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrInput, 400, slog.LevelDebug)
|
h.handleError(ctx, w, err.Error(), model.ErrInput, 400, slog.LevelDebug)
|
||||||
return
|
return
|
||||||
@ -32,19 +30,7 @@ func (h *Handel) Reg() http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
err = h.webService.Reg(ctx, u, rip, ip)
|
err = h.webService.Reg(ctx, u, rip, ip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, service.ErrExistUser) {
|
h.handleErrorService(ctx, w, err)
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrExistUser, 400, slog.LevelDebug)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if errors.Is(err, service.ErrExitsName) {
|
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrExitsName, 400, slog.LevelDebug)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if errors.Is(err, service.ErrRegLimit) {
|
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrRegLimit, 400, slog.LevelDebug)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrService, 500, slog.LevelWarn)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
encodeJson(w, model.API[any]{
|
encodeJson(w, model.API[any]{
|
||||||
@ -53,6 +39,33 @@ func (h *Handel) Reg() http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *Handel) Login() http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
|
ip, err := utils.GetIP(r)
|
||||||
|
if err != nil {
|
||||||
|
h.handleError(ctx, w, err.Error(), model.ErrInput, 400, slog.LevelDebug)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
l, err := utils.DeCodeBody[model.Login](r.Body, h.validate)
|
||||||
|
if err != nil {
|
||||||
|
h.handleError(ctx, w, err.Error(), model.ErrInput, 400, slog.LevelDebug)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
lr, err := h.webService.Login(ctx, l, ip)
|
||||||
|
if err != nil {
|
||||||
|
h.handleErrorService(ctx, w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
encodeJson(w, model.API[model.LoginRep]{
|
||||||
|
Code: 0,
|
||||||
|
Data: lr,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (h *Handel) UserInfo() http.HandlerFunc {
|
func (h *Handel) UserInfo() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
@ -81,11 +94,7 @@ func (h *Handel) ChangePasswd() http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
err = h.webService.ChangePasswd(ctx, c, t)
|
err = h.webService.ChangePasswd(ctx, c, t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, service.ErrPassWord) {
|
h.handleErrorService(ctx, w, err)
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrPassWord, 401, slog.LevelDebug)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrService, 500, slog.LevelWarn)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
encodeJson(w, model.API[any]{
|
encodeJson(w, model.API[any]{
|
||||||
@ -106,11 +115,7 @@ func (h *Handel) ChangeName() http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
err = h.webService.ChangeName(ctx, c.Name, t)
|
err = h.webService.ChangeName(ctx, c.Name, t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, service.ErrExitsName) {
|
h.handleErrorService(ctx, w, err)
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrExitsName, 400, slog.LevelDebug)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrService, 500, slog.LevelWarn)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
encodeJson(w, model.API[any]{
|
encodeJson(w, model.API[any]{
|
||||||
|
@ -13,4 +13,6 @@ const (
|
|||||||
ErrPassWord
|
ErrPassWord
|
||||||
ErrExitsName
|
ErrExitsName
|
||||||
ErrNotAdmin
|
ErrNotAdmin
|
||||||
|
ErrUserDisable
|
||||||
|
ErrCaptcha
|
||||||
)
|
)
|
||||||
|
@ -13,7 +13,7 @@ type List[T any] struct {
|
|||||||
List []T `json:"list"`
|
List []T `json:"list"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type User struct {
|
type UserReg struct {
|
||||||
Email string `validate:"required,email"`
|
Email string `validate:"required,email"`
|
||||||
Password string `validate:"required,min=6,max=50"`
|
Password string `validate:"required,min=6,max=50"`
|
||||||
Name string `validate:"required,min=3,max=16"`
|
Name string `validate:"required,min=3,max=16"`
|
||||||
@ -71,3 +71,15 @@ type EditUser struct {
|
|||||||
IsDisable bool `json:"is_disable"`
|
IsDisable bool `json:"is_disable"`
|
||||||
DelTextures bool `json:"del_textures"`
|
DelTextures bool `json:"del_textures"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Login struct {
|
||||||
|
Email string `json:"email" validate:"required,email"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
CaptchaToken string
|
||||||
|
}
|
||||||
|
|
||||||
|
type LoginRep struct {
|
||||||
|
Token string `json:"token"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
UUID string `json:"uuid"`
|
||||||
|
}
|
||||||
|
@ -66,7 +66,8 @@ func newYggdrasil(handelY *yggdrasil.Yggdrasil) http.Handler {
|
|||||||
func newSkinApi(handel *handle.Handel) http.Handler {
|
func newSkinApi(handel *handle.Handel) http.Handler {
|
||||||
r := chi.NewRouter()
|
r := chi.NewRouter()
|
||||||
|
|
||||||
r.Put("/user/reg", handel.Reg())
|
r.Post("/user/reg", handel.Reg())
|
||||||
|
r.Post("/user/login", handel.Login())
|
||||||
r.Get("/config", handel.GetConfig())
|
r.Get("/config", handel.GetConfig())
|
||||||
|
|
||||||
r.Group(func(r chi.Router) {
|
r.Group(func(r chi.Router) {
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"github.com/xmdhs/authlib-skin/db/ent"
|
"github.com/xmdhs/authlib-skin/db/ent"
|
||||||
"github.com/xmdhs/authlib-skin/db/ent/predicate"
|
"github.com/xmdhs/authlib-skin/db/ent/predicate"
|
||||||
@ -79,6 +80,7 @@ func (w *WebService) ListUser(ctx context.Context, page int, email, name string)
|
|||||||
|
|
||||||
func (w *WebService) EditUser(ctx context.Context, u model.EditUser, uid int) error {
|
func (w *WebService) EditUser(ctx context.Context, u model.EditUser, uid int) error {
|
||||||
uuid := ""
|
uuid := ""
|
||||||
|
changePasswd := false
|
||||||
err := utils.WithTx(ctx, w.client, func(tx *ent.Tx) error {
|
err := utils.WithTx(ctx, w.client, func(tx *ent.Tx) error {
|
||||||
up := tx.User.UpdateOneID(uid).SetEmail(u.Email)
|
up := tx.User.UpdateOneID(uid).SetEmail(u.Email)
|
||||||
if u.Password != "" {
|
if u.Password != "" {
|
||||||
@ -88,6 +90,7 @@ func (w *WebService) EditUser(ctx context.Context, u model.EditUser, uid int) er
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
changePasswd = true
|
||||||
}
|
}
|
||||||
err := tx.UserProfile.Update().Where(userprofile.HasUserWith(user.ID(uid))).SetName(u.Name).Exec(ctx)
|
err := tx.UserProfile.Update().Where(userprofile.HasUserWith(user.ID(uid))).SetName(u.Name).Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -134,5 +137,11 @@ func (w *WebService) EditUser(ctx context.Context, u model.EditUser, uid int) er
|
|||||||
return fmt.Errorf("EditUser: %w", err)
|
return fmt.Errorf("EditUser: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if changePasswd {
|
||||||
|
err = w.cache.Del([]byte("auth" + strconv.Itoa(uid)))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("EditUser: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
@ -26,6 +27,8 @@ type turnstileRet struct {
|
|||||||
ErrorCodes []string `json:"error-codes"`
|
ErrorCodes []string `json:"error-codes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ErrCaptcha = errors.New("验证码错误")
|
||||||
|
|
||||||
type ErrTurnstile struct {
|
type ErrTurnstile struct {
|
||||||
ErrorCodes []string
|
ErrorCodes []string
|
||||||
}
|
}
|
||||||
@ -34,7 +37,10 @@ func (e ErrTurnstile) Error() string {
|
|||||||
return strings.Join(e.ErrorCodes, " ")
|
return strings.Join(e.ErrorCodes, " ")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WebService) verifyTurnstile(ctx context.Context, token, ip string) error {
|
func (w *WebService) verifyCaptcha(ctx context.Context, token, ip string) error {
|
||||||
|
if w.config.Captcha.Type != "turnstile" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
bw := &bytes.Buffer{}
|
bw := &bytes.Buffer{}
|
||||||
err := json.NewEncoder(bw).Encode(turnstileResponse{
|
err := json.NewEncoder(bw).Encode(turnstileResponse{
|
||||||
Secret: w.config.Captcha.Secret,
|
Secret: w.config.Captcha.Secret,
|
||||||
@ -63,9 +69,9 @@ func (w *WebService) verifyTurnstile(ctx context.Context, token, ip string) erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !t.Success {
|
if !t.Success {
|
||||||
return fmt.Errorf("verifyTurnstile: %w", ErrTurnstile{
|
return fmt.Errorf("verifyTurnstile: %w", errors.Join(ErrTurnstile{
|
||||||
ErrorCodes: t.ErrorCodes,
|
ErrorCodes: t.ErrorCodes,
|
||||||
})
|
}, ErrCaptcha))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ var (
|
|||||||
ErrChangeName = errors.New("离线模式 uuid 不允许修改用户名")
|
ErrChangeName = errors.New("离线模式 uuid 不允许修改用户名")
|
||||||
)
|
)
|
||||||
|
|
||||||
func (w *WebService) Reg(ctx context.Context, u model.User, ipPrefix, ip string) error {
|
func (w *WebService) Reg(ctx context.Context, u model.UserReg, ipPrefix, ip string) error {
|
||||||
var userUuid string
|
var userUuid string
|
||||||
if w.config.OfflineUUID {
|
if w.config.OfflineUUID {
|
||||||
userUuid = utils.UUIDGen(u.Name)
|
userUuid = utils.UUIDGen(u.Name)
|
||||||
@ -33,11 +33,9 @@ func (w *WebService) Reg(ctx context.Context, u model.User, ipPrefix, ip string)
|
|||||||
userUuid = strings.ReplaceAll(uuid.New().String(), "-", "")
|
userUuid = strings.ReplaceAll(uuid.New().String(), "-", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
if w.config.Captcha.Type == "turnstile" {
|
err := w.verifyCaptcha(ctx, u.CaptchaToken, ip)
|
||||||
err := w.verifyTurnstile(ctx, u.CaptchaToken, ip)
|
if err != nil {
|
||||||
if err != nil {
|
return fmt.Errorf("Reg: %w", err)
|
||||||
return fmt.Errorf("Reg: %w", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if w.config.MaxIpUser != 0 {
|
if w.config.MaxIpUser != 0 {
|
||||||
@ -52,7 +50,7 @@ func (w *WebService) Reg(ctx context.Context, u model.User, ipPrefix, ip string)
|
|||||||
|
|
||||||
p, s := utils.Argon2ID(u.Password)
|
p, s := utils.Argon2ID(u.Password)
|
||||||
|
|
||||||
err := utils.WithTx(ctx, w.client, func(tx *ent.Tx) error {
|
err = utils.WithTx(ctx, w.client, func(tx *ent.Tx) error {
|
||||||
count, err := tx.User.Query().Where(user.EmailEQ(u.Email)).ForUpdate().Count(ctx)
|
count, err := tx.User.Query().Where(user.EmailEQ(u.Email)).ForUpdate().Count(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -93,6 +91,30 @@ func (w *WebService) Reg(ctx context.Context, u model.User, ipPrefix, ip string)
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *WebService) Login(ctx context.Context, l model.Login, ip string) (model.LoginRep, error) {
|
||||||
|
err := w.verifyCaptcha(ctx, l.CaptchaToken, ip)
|
||||||
|
if err != nil {
|
||||||
|
return model.LoginRep{}, fmt.Errorf("Login: %w", err)
|
||||||
|
}
|
||||||
|
u, err := w.client.User.Query().Where(user.Email(l.Email)).WithProfile().Only(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return model.LoginRep{}, fmt.Errorf("Login: %w", err)
|
||||||
|
}
|
||||||
|
err = w.validatePass(ctx, u, l.Password)
|
||||||
|
if err != nil {
|
||||||
|
return model.LoginRep{}, fmt.Errorf("Login: %w", err)
|
||||||
|
}
|
||||||
|
jwt, err := utilsService.CreateToken(ctx, u, w.client, w.cache, w.prikey, "web")
|
||||||
|
if err != nil {
|
||||||
|
return model.LoginRep{}, fmt.Errorf("Login: %w", err)
|
||||||
|
}
|
||||||
|
return model.LoginRep{
|
||||||
|
Token: jwt,
|
||||||
|
Name: u.Edges.Profile.Name,
|
||||||
|
UUID: u.Edges.Profile.UUID,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (w *WebService) Info(ctx context.Context, t *model.TokenClaims) (model.UserInfo, error) {
|
func (w *WebService) Info(ctx context.Context, t *model.TokenClaims) (model.UserInfo, error) {
|
||||||
u, err := w.client.User.Query().Where(user.ID(t.UID)).First(ctx)
|
u, err := w.client.User.Query().Where(user.ID(t.UID)).First(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -111,8 +133,9 @@ func (w *WebService) ChangePasswd(ctx context.Context, p model.ChangePasswd, t *
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("ChangePasswd: %w", err)
|
return fmt.Errorf("ChangePasswd: %w", err)
|
||||||
}
|
}
|
||||||
if !utils.Argon2Compare(p.Old, u.Password, u.Salt) {
|
err = w.validatePass(ctx, u, p.Old)
|
||||||
return fmt.Errorf("ChangePasswd: %w", ErrPassWord)
|
if err != nil {
|
||||||
|
return fmt.Errorf("ChangePasswd: %w", err)
|
||||||
}
|
}
|
||||||
pass, salt := utils.Argon2ID(p.New)
|
pass, salt := utils.Argon2ID(p.New)
|
||||||
if u.Edges.Token != nil {
|
if u.Edges.Token != nil {
|
||||||
|
@ -15,10 +15,12 @@ import (
|
|||||||
"github.com/xmdhs/authlib-skin/db/ent/usertoken"
|
"github.com/xmdhs/authlib-skin/db/ent/usertoken"
|
||||||
"github.com/xmdhs/authlib-skin/model"
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
||||||
|
"github.com/xmdhs/authlib-skin/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrTokenInvalid = errors.New("token 无效")
|
ErrTokenInvalid = errors.New("token 无效")
|
||||||
|
ErrUserDisable = errors.New("用户被禁用")
|
||||||
)
|
)
|
||||||
|
|
||||||
func Auth(ctx context.Context, t yggdrasil.ValidateToken, client *ent.Client, c cache.Cache, pubkey *rsa.PublicKey, tmpInvalid bool) (*model.TokenClaims, error) {
|
func Auth(ctx context.Context, t yggdrasil.ValidateToken, client *ent.Client, c cache.Cache, pubkey *rsa.PublicKey, tmpInvalid bool) (*model.TokenClaims, error) {
|
||||||
@ -80,6 +82,63 @@ func Auth(ctx context.Context, t yggdrasil.ValidateToken, client *ent.Client, c
|
|||||||
return claims, nil
|
return claims, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CreateToken(ctx context.Context, u *ent.User, client *ent.Client, cache cache.Cache, jwtKey *rsa.PrivateKey, clientToken string) (string, error) {
|
||||||
|
if IsDisable(u.State) {
|
||||||
|
return "", fmt.Errorf("CreateToken: %w", ErrUserDisable)
|
||||||
|
}
|
||||||
|
var utoken *ent.UserToken
|
||||||
|
err := utils.WithTx(ctx, client, func(tx *ent.Tx) error {
|
||||||
|
var err error
|
||||||
|
utoken, err = tx.User.QueryToken(u).ForUpdate().First(ctx)
|
||||||
|
if err != nil {
|
||||||
|
var nf *ent.NotFoundError
|
||||||
|
if !errors.As(err, &nf) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if utoken == nil {
|
||||||
|
ut, err := tx.UserToken.Create().SetTokenID(1).SetUser(u).Save(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
utoken = ut
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("CreateToken: %w", err)
|
||||||
|
}
|
||||||
|
err = cache.Del([]byte("auth" + strconv.Itoa(u.ID)))
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("CreateToken: %w", err)
|
||||||
|
}
|
||||||
|
t, err := NewJwtToken(jwtKey, strconv.FormatUint(utoken.TokenID, 10), clientToken, u.Edges.Profile.UUID, u.ID)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("CreateToken: %w", err)
|
||||||
|
}
|
||||||
|
return t, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewJwtToken(jwtKey *rsa.PrivateKey, tokenID, clientToken, UUID string, userID int) (string, error) {
|
||||||
|
claims := model.TokenClaims{
|
||||||
|
Tid: tokenID,
|
||||||
|
CID: clientToken,
|
||||||
|
UID: userID,
|
||||||
|
RegisteredClaims: jwt.RegisteredClaims{
|
||||||
|
ExpiresAt: jwt.NewNumericDate(time.Now().Add(15 * 24 * time.Hour)),
|
||||||
|
Issuer: "authlib-skin",
|
||||||
|
Subject: UUID,
|
||||||
|
IssuedAt: jwt.NewNumericDate(time.Now()),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
|
||||||
|
jwts, err := token.SignedString(jwtKey)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("newJwtToken: %w", err)
|
||||||
|
}
|
||||||
|
return jwts, nil
|
||||||
|
}
|
||||||
|
|
||||||
func IsAdmin(state int) bool {
|
func IsAdmin(state int) bool {
|
||||||
return state&1 == 1
|
return state&1 == 1
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/xmdhs/authlib-skin/config"
|
"github.com/xmdhs/authlib-skin/config"
|
||||||
"github.com/xmdhs/authlib-skin/db/cache"
|
"github.com/xmdhs/authlib-skin/db/cache"
|
||||||
"github.com/xmdhs/authlib-skin/db/ent"
|
"github.com/xmdhs/authlib-skin/db/ent"
|
||||||
|
"github.com/xmdhs/authlib-skin/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type WebService struct {
|
type WebService struct {
|
||||||
@ -26,3 +29,10 @@ func NewWebService(c config.Config, e *ent.Client, hc *http.Client, cache cache.
|
|||||||
prikey: prikey,
|
prikey: prikey,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *WebService) validatePass(ctx context.Context, u *ent.User, password string) error {
|
||||||
|
if !utils.Argon2Compare(password, u.Password, u.Salt) {
|
||||||
|
return fmt.Errorf("validatePass: %w", ErrPassWord)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -62,49 +62,19 @@ func (y *Yggdrasil) Authenticate(cxt context.Context, auth yggdrasil.Authenticat
|
|||||||
return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", err)
|
return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if sutils.IsDisable(u.State) {
|
|
||||||
return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", ErrUserDisable)
|
|
||||||
}
|
|
||||||
|
|
||||||
clientToken := auth.ClientToken
|
clientToken := auth.ClientToken
|
||||||
if clientToken == "" {
|
if clientToken == "" {
|
||||||
clientToken = strings.ReplaceAll(uuid.New().String(), "-", "")
|
clientToken = strings.ReplaceAll(uuid.New().String(), "-", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
var utoken *ent.UserToken
|
jwts, err := sutils.CreateToken(cxt, u, y.client, y.cache, y.prikey, clientToken)
|
||||||
err = utils.WithTx(cxt, y.client, func(tx *ent.Tx) error {
|
|
||||||
utoken, err = tx.User.QueryToken(u).ForUpdate().First(cxt)
|
|
||||||
if err != nil {
|
|
||||||
var nf *ent.NotFoundError
|
|
||||||
if !errors.As(err, &nf) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if utoken == nil {
|
|
||||||
ut, err := tx.UserToken.Create().SetTokenID(1).SetUser(u).Save(cxt)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
utoken = ut
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", err)
|
|
||||||
}
|
|
||||||
err = y.cache.Del([]byte("auth" + strconv.Itoa(u.ID)))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", err)
|
return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if u.Edges.Profile == nil {
|
if u.Edges.Profile == nil {
|
||||||
return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", ErrUserDisable)
|
return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", ErrUserDisable)
|
||||||
}
|
}
|
||||||
|
|
||||||
jwts, err := newJwtToken(y.prikey, strconv.FormatUint(utoken.TokenID, 10), clientToken, u.Edges.Profile.UUID, u.ID)
|
|
||||||
if err != nil {
|
|
||||||
return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
p := yggdrasil.UserInfo{
|
p := yggdrasil.UserInfo{
|
||||||
ID: u.Edges.Profile.UUID,
|
ID: u.Edges.Profile.UUID,
|
||||||
Name: u.Edges.Profile.Name,
|
Name: u.Edges.Profile.Name,
|
||||||
|
@ -7,7 +7,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/golang-jwt/jwt/v5"
|
|
||||||
"github.com/xmdhs/authlib-skin/config"
|
"github.com/xmdhs/authlib-skin/config"
|
||||||
"github.com/xmdhs/authlib-skin/db/cache"
|
"github.com/xmdhs/authlib-skin/db/cache"
|
||||||
"github.com/xmdhs/authlib-skin/db/ent"
|
"github.com/xmdhs/authlib-skin/db/ent"
|
||||||
@ -67,23 +66,7 @@ func putUint(n uint64, c cache.Cache, key []byte, d time.Duration) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newJwtToken(jwtKey *rsa.PrivateKey, tokenID, clientToken, UUID string, userID int) (string, error) {
|
func newJwtToken(jwtKey *rsa.PrivateKey, tokenID, clientToken, UUID string, userID int) (string, error) {
|
||||||
claims := model.TokenClaims{
|
return sutils.NewJwtToken(jwtKey, tokenID, clientToken, UUID, userID)
|
||||||
Tid: tokenID,
|
|
||||||
CID: clientToken,
|
|
||||||
UID: userID,
|
|
||||||
RegisteredClaims: jwt.RegisteredClaims{
|
|
||||||
ExpiresAt: jwt.NewNumericDate(time.Now().Add(15 * 24 * time.Hour)),
|
|
||||||
Issuer: "authlib-skin",
|
|
||||||
Subject: UUID,
|
|
||||||
IssuedAt: jwt.NewNumericDate(time.Now()),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
|
|
||||||
jwts, err := token.SignedString(jwtKey)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("newJwtToken: %w", err)
|
|
||||||
}
|
|
||||||
return jwts, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (y *Yggdrasil) Auth(ctx context.Context, t yggdrasil.ValidateToken) (*model.TokenClaims, error) {
|
func (y *Yggdrasil) Auth(ctx context.Context, t yggdrasil.ValidateToken) (*model.TokenClaims, error) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user