Compare commits
21 Commits
b41fdd7816
...
07b3a61fac
Author | SHA1 | Date |
---|---|---|
熊二 | 07b3a61fac | 2 years ago |
熊二 | 3c3f18b251 | 2 years ago |
熊二 | bf8051c8b4 | 2 years ago |
熊二 | 29e368f6d0 | 2 years ago |
熊二 | cf16b63845 | 2 years ago |
熊二 | b56bce9de7 | 2 years ago |
熊二 | d0d131dd09 | 2 years ago |
熊二 | e866ed3e3b | 2 years ago |
熊二 | 88668e63c3 | 2 years ago |
熊二 | c2eb20d5ed | 2 years ago |
熊二 | 39413b9a9c | 2 years ago |
熊二 | 6a5b54ced7 | 2 years ago |
熊二 | df6243f6d3 | 2 years ago |
熊二 | c0540a6483 | 2 years ago |
熊二 | 8151116592 | 2 years ago |
熊二 | 583e1b72d0 | 2 years ago |
熊二 | b6feff6085 | 2 years ago |
熊二 | a48c1056c1 | 2 years ago |
熊二 | 5114a32c6d | 2 years ago |
熊二 | f65ef3e7d0 | 2 years ago |
熊二 | 460dc378ea | 2 years ago |
@ -0,0 +1,124 @@ |
|||||||
|
package app |
||||||
|
|
||||||
|
import ( |
||||||
|
"context" |
||||||
|
"errors" |
||||||
|
"github.com/go-chi/jwtauth/v5" |
||||||
|
"github.com/lestrrat-go/jwx/v2/jwt" |
||||||
|
"github.com/rs/xid" |
||||||
|
"golang.org/x/crypto/bcrypt" |
||||||
|
"gorm.io/gorm" |
||||||
|
"net/http" |
||||||
|
"time" |
||||||
|
) |
||||||
|
|
||||||
|
func HashPassword(password string) (string, error) { |
||||||
|
bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14) |
||||||
|
return string(bytes), err |
||||||
|
} |
||||||
|
|
||||||
|
func CheckPasswordHash(password, hash string) bool { |
||||||
|
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) |
||||||
|
return err == nil |
||||||
|
} |
||||||
|
|
||||||
|
func GenerateAuthToken(r *Request, uid uint) (*UserToken, error) { |
||||||
|
code := xid.New().String() |
||||||
|
|
||||||
|
rawToken, err := jwt.NewBuilder(). |
||||||
|
//Audience().
|
||||||
|
Expiration(time.Now().Add(time.Hour*24)). |
||||||
|
Issuer(r.URL.Hostname()). |
||||||
|
IssuedAt(time.Now()). |
||||||
|
//JwtID().
|
||||||
|
//NotBefore().
|
||||||
|
//Subject().
|
||||||
|
Claim("code", code). |
||||||
|
Build() |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
claims, err := rawToken.AsMap(r.Context()) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
_, accessToken, err := tokenAuth.Encode(claims) |
||||||
|
if err != nil { |
||||||
|
return nil, NewError(1, "生成授权令牌失败") |
||||||
|
} |
||||||
|
|
||||||
|
if err = rawToken.Set(jwt.ExpirationKey, time.Now().Add(time.Hour*24*30)); err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
if claims, err = rawToken.AsMap(r.Context()); err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
_, refreshToken, err := tokenAuth.Encode(claims) |
||||||
|
if err != nil { |
||||||
|
return nil, NewError(1, "生成刷新令牌失败") |
||||||
|
} |
||||||
|
|
||||||
|
return &UserToken{ |
||||||
|
Code: code, |
||||||
|
UserID: uid, |
||||||
|
AccessToken: accessToken, |
||||||
|
RefreshToken: refreshToken, |
||||||
|
CreatedAt: time.Now(), |
||||||
|
}, nil |
||||||
|
} |
||||||
|
|
||||||
|
func AuthInfo(r *Request) (*UserToken, error) { |
||||||
|
token, _, err := jwtauth.FromContext(r.Context()) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
code, ok := token.Get("code") |
||||||
|
if !ok { |
||||||
|
return nil, ErrInvalidToken |
||||||
|
} |
||||||
|
if _, ok = code.(string); !ok { |
||||||
|
return nil, ErrInvalidToken |
||||||
|
} |
||||||
|
|
||||||
|
var ut UserToken |
||||||
|
err = DB.Model(&UserToken{}).Preload("User").First(&ut, "code = ?", code).Error |
||||||
|
if err != nil { |
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) { |
||||||
|
return nil, ErrInvalidToken |
||||||
|
} |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
return &ut, nil |
||||||
|
} |
||||||
|
|
||||||
|
var ErrInvalidToken = &Error{ |
||||||
|
Status: http.StatusForbidden, |
||||||
|
Code: 401, |
||||||
|
Message: "错误令牌", |
||||||
|
} |
||||||
|
|
||||||
|
func CheckAuthToken(next http.Handler) http.Handler { |
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
||||||
|
token, _, _ := jwtauth.FromContext(r.Context()) |
||||||
|
if code, ok := token.Get("code"); !ok { |
||||||
|
NewResponseWriter(w).Error(ErrInvalidToken) |
||||||
|
} else if codeString, ok := code.(string); !ok { |
||||||
|
NewResponseWriter(w).Error(ErrInvalidToken) |
||||||
|
} else if _, err := xid.FromString(codeString); err != nil { |
||||||
|
NewResponseWriter(w).Error(ErrInvalidToken) |
||||||
|
} else { |
||||||
|
var ut UserToken |
||||||
|
err = DB.First(&ut, "code = ?", codeString).Error |
||||||
|
if err != nil { |
||||||
|
NewResponseWriter(w).Error(ErrInvalidToken) |
||||||
|
} else { |
||||||
|
ctx := context.WithValue(r.Context(), "USER_TOKEN", &ut) |
||||||
|
next.ServeHTTP(w, r.WithContext(ctx)) |
||||||
|
} |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
Loading…
Reference in new issue