Beego + JWT实现用户登录与注册

1. Beego 安装

安装或者升级 Beego 和 Bee 的开发工具:

go get -u github.com/astaxie/beego
go get -u github.com/beego/bee

Beego是快速开发 Go 应用的 HTTP 框架,可以用来快速开发 API、Web 及后端服务等各种应用,其官方教程 https://beego.me/quickstart

2. JWT 安装 

go get github.com/dgrijalva/jwt-go

 JWT(Json web token) 是目前最流行的跨域认证解决方案之一,其官网文档 https://jwt.io/introduction/ 

3. Beego + JWT 实现登录注册

(1)Jwt 实现

// generate token
func GenerateToken(loginInfo *LoginRequest, userID int, expiredSeconds int) (tokenString string, err error) {
	if expiredSeconds == 0 {
		expiredSeconds = DEFAULT_EXPIRE_SECONDS
	}

	// Create the Claims
	mySigningKey := []byte(SecretKEY)
	expireAt := time.Now().Add(time.Second * time.Duration(expiredSeconds)).Unix()
	logs.Info("Token will be expired at ", time.Unix(expireAt, 0))

	user := *loginInfo
	claims := MyCustomClaims{
		userID,
		jwt.StandardClaims{
			Issuer:    user.Username,
			IssuedAt:  time.Now().Unix(),
			ExpiresAt: expireAt,
		},
	}

	// Create the token using your claims
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	// Signs the token with a secret
	tokenStr, err := token.SignedString(mySigningKey)
	if err != nil {
		return "", errors.New("error: failed to generate token")
	}

	return tokenStr, nil
}

(2)controller(登录和注册)

// Login handles login request
func (u *UserController) Login() {
	lr := new(models.LoginRequest)

	if err := u.unmarshalPayload(lr); err != nil {
		u.respond(http.StatusBadRequest, err.Error())
		return
	}

	lrs, statusCode, err := models.DoLogin(lr)
	if err != nil {
		u.respond(statusCode, err.Error())
		return
	}

	u.Ctx.Output.Header("Authorization", lrs.Token) // set token into header
	u.respond(http.StatusOK, "", lrs)
}

// CreateUser creates a user
func (u *UserController) CreateUser() {
	cu := new(models.CreateRequest)

	if err := u.unmarshalPayload(cu); err != nil {
		u.respond(http.StatusBadRequest, err.Error())
	}

	createUser, statusCode, err := models.DoCreateUser(cu)
	if err != nil {
		u.respond(statusCode, err.Error())
		return
	}

	u.respond(http.StatusOK, "", createUser)
}

(3)model(登录和注册) 

// DoLogin: user login
func DoLogin(lr *LoginRequest) (*LoginResponse, int, error) {
	// get username and password
	username := lr.Username
	password := lr.Password

	//validate username and password if is empty
	if len(username) == 0 || len(password) == 0 {
		return nil, http.StatusBadRequest, errors.New("error: username or password is empty")
	}

	// connect db
	o := orm.NewOrm()

	// check the username if existing
	user := &User{Username: username}
	err := o.Read(user, "username")
	if err != nil {
		return nil, http.StatusBadRequest, errors.New("error: username is not existing")
	}

	// generate the password hash
	hash, err := GeneratePassHash(password, user.Salt)
	if err != nil {
		return nil, http.StatusBadRequest, err
	}
	if hash != user.Password {
		return nil, http.StatusBadRequest, errors.New("error: password is error")
	}

	// generate token
	tokenString, err := GenerateToken(lr, user.Id, 0)
	if err != nil {
		return nil, http.StatusBadRequest, err
	}

	return &LoginResponse{
		Username:    user.Username,
		UserID:      user.Id,
		Token:       tokenString,
	}, http.StatusOK, nil
}

// DoCreateUser: create a user
func DoCreateUser(cr *CreateRequest) (*CreateResponse, int, error) {
	// connect db
	o := orm.NewOrm()

	// check username if exist
	userNameCheck := User{Username: cr.Username}
	err := o.Read(&userNameCheck, "username")
	if err == nil {
		return nil, http.StatusBadRequest, errors.New("username has already existed")
	}

	// generate salt
	saltKey, err := GenerateSalt()
	if err != nil {
		logs.Info(err.Error())
		return nil, http.StatusBadRequest, err
	}

	// generate password hash
	hash, err := GeneratePassHash(cr.Password, saltKey)
	if err != nil {
		logs.Info(err.Error())
		return nil, http.StatusBadRequest, err
	}

	// create user
	user := User{}
	user.Username = cr.Username
	user.Password = hash
	user.Salt = saltKey

	_, err = o.Insert(&user)
	if err != nil {
		logs.Info(err.Error())
		return nil, http.StatusBadRequest, err
	}

	return &CreateResponse{
		UserID:   user.Id,
		Username: user.Username,
	}, http.StatusOK, nil

}

完整的代码可见github: https://github.com/Messi-Q/Beego-Jwt


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_34611579/article/details/107978341