【golang自学之路】实现一账号N地登录问题!redis+JWT实现详讲
在这个例子中,我们将使用Redis和JWT来实现一账N地登录。
首先,我们需要安装Redis和相关的Go包:
go get -u github.com/go-redis/redis/v8
go get -u github.com/golang-jwt/jwt/v4
以下是核心函数的实现:
package main
import (
"context"
"crypto/rand"
"crypto/rsa"
"encoding/json"
"fmt"
"github.com/go-redis/redis/v8"
"github.com/golang-jwt/jwt/v4"
"log"
"time"
)
var (
redisClient *redis.Client
privateKey *rsa.PrivateKey
publicKey rsa.PublicKey
)
type UserInfo struct {
Username string `json:"username"`
Password string `json:"password"`
}
type Payload struct {
jwt.Payload
UserInfo
}
func init() {
redisClient = redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password set
DB: 0, // use default DB
})
// 生成私钥和公钥
var err error
privateKey, err = rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
log.Fatalf("failed to generate private key: %v", err)
}
publicKey = privateKey.PublicKey
}
func createToken(userInfo UserInfo) (string, error) {
payload := Payload{
Payload: jwt.NewWithConfig(jwt.GetSigningMethod("RS256"), jwt.StandardClaims{
Issuer: "example",
Subject: userInfo.Username,
IssuedAt: time.Now(),
ExpiresAt: time.Now().Add(time.Hour * 24), // 设置token有效期1天
}),
UserInfo: userInfo,
}
token, err := jwt.Sign(&payload, jwt.NewRS256(privateKey))
if err != nil {
return "", err
}
return token, nil
}
func login(username, password string) (string, error) {
ctx := context.Background()
userKey := fmt.Sprintf("user:%s", username)
userInfoBytes, err := redisClient.Get(ctx, userKey).Bytes()
if err != nil {
return "", err
}
var userInfo UserInfo
if err := json.Unmarshal(userInfoBytes, &userInfo); err != nil {
return "", err
}
if userInfo.Password != password {
return "", fmt.Errorf("invalid password")
}
token, err := createToken(userInfo)
if err != nil {
return "", err
}
return token, nil
}
func main() {
// 假设用户已经在其他地方登录,并且我们已经有了他们的凭证
token, err := login("user1", "password123")
if err != nil {
log.Fatalf("login failed: %v", err)
}
fmt.Printf("Token: %s\n", token)
}
在这个例子中,我们首先初始化了Redis客户端,并生成了一对私钥和公钥,用于签发JWT。然后我们实现了createToken
函数,它使用私钥来签发JWT。login
函数会从Redis中获取用户信息,验证密码,如果验证通过,则为用户签发新的Tok
评论已关闭