Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Beego #12

Open
chengtm opened this issue Sep 24, 2019 · 0 comments
Open

Beego #12

chengtm opened this issue Sep 24, 2019 · 0 comments

Comments

@chengtm
Copy link
Owner

chengtm commented Sep 24, 2019

  • 准备工作
  1. cd /Users/rouchi/go,即进入GOPATH路径下,执行命令:
    go get github.com/astaxie/beego
    go get github.com/beego/bee
    下载beego与bee安装包,可以看到路径下多了src,pkg,bin三个文件夹
    此时可以通过bee命令创建项目:
    bee new achievement
    cd achievement
    bee run
    如果提示-bash: bee: command not found,记得检查环境变量。
  2. bee new命令创建的web项目,可以开发后端与页面。也可以通过bee api命令创建纯后端的项目。如下:
    bee api beeapi
    cd beeapi
    bee run -downdoc=true -gendoc=true
  3. 在浏览器中输入:http://127.0.0.1:8080/swagger/
  • bcrypt包用来给密码加密解密
  1. 下载安装包:go get golang.org/x/crypto/bcrypt,或者在指定目录下下载bcrypt源码
  2. 验证密码,明文和加密之后的密码做对比:bcrypt.CompareHashAndPassword([]byte(m.Password), []byte(password))
  3. 给密码加密:passwordHash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
  • 通过jwt生成token
  1. 下载安装包:go get github.com/dgrijalva/jwt-go
  2. 运用:
package controllers

import (
	"errors"
	"time"

	"github.com/dgrijalva/jwt-go"
)

var (
	Secret = "test_secret" // 加盐
)

type JWTClaims struct {  // token里面添加用户信息,验证token后可能会用到用户信息
	jwt.StandardClaims
	Id      int     `json:"id"`
}

func (c *JWTClaims) SetExpiredAt(expiredAt int64) {
	c.ExpiresAt = expiredAt
}

// 生成token
func GenerateToken(id int, expiration int) (string, error){
	claims := JWTClaims{
		Id:      id,
	}
	claims.IssuedAt = time.Now().Unix()
	claims.SetExpiredAt(time.Now().Add(time.Second * time.Duration(expiration)).Unix())

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	return token.SignedString([]byte(Secret))
}

// 刷新token
func RefreshToken(strToken string) (string, error) {
	token, err := jwt.ParseWithClaims(strToken, &JWTClaims{}, func(token *jwt.Token) (interface{}, error) {
		return []byte(Secret), nil
	})
	if err != nil {
		return "", err
	}
	claims, ok := token.Claims.(*JWTClaims)
	if !ok {
		println("test")
		return "", errors.New("ceshi")
	}
	if err := token.Claims.Valid(); err != nil {
		println(err)
		return "", err
	}

	claims.Id = 1
	claims.ExpiresAt = time.Now().Unix() + (claims.ExpiresAt - claims.IssuedAt)

	newToken := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	signedToken, err := newToken.SignedString([]byte(Secret))
	if err != nil {
		println(err)
		return "", err
	}
	return signedToken, nil
}

// 验证token是否有效
func VerifyToken(strToken string) (int, error) {
	token, err := jwt.ParseWithClaims(strToken, &JWTClaims{}, func(token *jwt.Token) (interface{}, error) {
		return []byte(Secret), nil
	})
	if err != nil {
		println(err)
		return 0, err
	}
	if err := token.Claims.Valid(); err != nil {
		print(err)
		return 0, err
	}
	claims, ok := token.Claims.(*JWTClaims)
	if !ok {
		return 0, err
	}
	return claims.Id, nil
}
  • 通过加过滤器做登录验证
package filter

import (
	"encoding/base64"
	"strings"

	"my_project/controllers"
	"my_project/models"

	"github.com/astaxie/beego"
	"github.com/astaxie/beego/context"
	"github.com/astaxie/beego/orm"
)


func getUser(mobile string, password string) (int, error) {
	o := orm.NewOrm()
	err := o.Using("default")
	if err != nil{
		return 0, nil
	}

	agent := models.Agent{Mobile:mobile}
	err = o.Read(&agent, "Mobile")
	if err != nil{
		return 0, err
	}
	err = agent.CheckPassword(password)
	if err != nil{
		return 0, err
	}
	return agent.Id, nil
}

var LoginRequired = func(ctx *context.Context) {
	auth := ctx.Input.Header("Authorization")

	if strings.HasPrefix(auth, "Basic") {
		b, err := base64.StdEncoding.DecodeString(strings.TrimPrefix(auth, "Basic "))
		if err != nil {
			ctx.Abort(401, "No authorization")
		}
		cred := string(b)
		pos := strings.IndexByte(cred, ':')
		if pos <= 0 {
			ctx.Abort(401, "No authorization")
		}

		cred0, cred1 := cred[:pos], cred[pos+1:]
		// Verify credentials
		// 登录时将"用户名:密码"做base64加密
		// 登录之后将后端返回的"token:token值"做base64加密
		if cred0 == "token" {
			userId, err := controllers.VerifyToken(cred1)
			if err != nil {
				ctx.Abort(401, "No authorization")
			}
			ctx.Input.SetData("userId", userId)
		} else {
			userId, err := getUser(cred0, cred1)
			if err != nil {
				ctx.Abort(401, "No authorization")
			}
			ctx.Input.SetData("userId", userId)
		}
	}else{
		ctx.Abort(401, "No authorization")
	}
}

func init() {
	beego.InsertFilter("/*", beego.BeforeRouter, LoginRequired)
}

  • orm模型定义

https://my.oschina.net/u/252343/blog/829912
https://beego.me/docs/install/bee.md
https://www.jianshu.com/p/0afdb7d92006

  • Beego前后端交互的三种方式

https://blog.csdn.net/qq_41147260/article/details/84644688

  • datetime的json格式化问题

https://segmentfault.com/a/1190000012066145

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant