golang simply implements JWT verification (beego, xorm, jwt)

Keywords: Go github JSON Database SQL

Program directory structure

Simple implementation, the user logs in and returns a jwt token. The next request takes a token to request the user information interface and return the information.

The app.conf file content (which can be read directly by a beego) is written as a jwt secretkey

jwtkey="12345678"

The user name and password of the connection database are stored in config.json (here we just learn how to read json's configuration file, which can be integrated into beego's app.conf file)

{
"sqltype":"mssql"
,"connstring":"server=.;port=1433;user id=sa;password=123;database=table1"
}

MSSqlHelper.go Implements Connecting mssqlserver's Database

package mssqlhelper
 
import (
	"fmt"
 
	"github.com/akkuman/parseConfig"
	_ "github.com/denisenkom/go-mssqldb"
	"github.com/go-xorm/core"
	"github.com/go-xorm/xorm"
)
 
// Create XORM client
func CreateClient() *xorm.Engine {
	var config = parseConfig.New("config.json")
	sqltype := config.Get("sqltype")
	fmt.Println(sqltype)
	connstring := config.Get("connstring")
	fmt.Println(connstring)
	engine, err := xorm.NewEngine(sqltype.(string), connstring.(string))
	if err != nil {
		println("open error:", &err)
	}
	engine.SetMapper(core.SameMapper{})      //The name of the class representing Struct is the same as in the database
	engine.ShowSQL(true)                     //Display SQL statements
	engine.Logger().SetLevel(core.LOG_DEBUG) //Print SQL statements
 
	return engine
}

AuthorizeController.go Implements User Login and Gets User Information Interface

package controller
 
import (
	"GoApi/DAL"
	"GoApi/Model"
	"encoding/json"
	"fmt"
	"net/http"
	"strconv"
	"strings"
	"time"
 
	"github.com/astaxie/beego/context"
 
	"github.com/astaxie/beego"
	jwt "github.com/dgrijalva/jwt-go"
	"github.com/go-xorm/xorm"
)
 
var engine *xorm.Engine
 
type AuthorizeController struct {
	beego.Controller
}
 
var filterUser = func(ctx *context.Context) {
	token := ctx.Input.Header("Authorization")
 
	b, _ := CheckToken(token)
 
	//Verify that Token is legal
	if !b {
		http.Error(ctx.ResponseWriter, "Token verification not pass", http.StatusBadRequest)
		return
	}
	fmt.Println("Request token:", token)
}
 
func init() {
	engine = mssqlhelper.CreateClient()
    //Verify token before accessing the interface
	beego.InsertFilter("/Authorize/Userinfo", beego.BeforeRouter, filterUser)
}
 
type Token struct {
	Token string `json:"token"`
}
 
func fatal(err error) {
	if err != nil {
		beego.Error(err)
	}
}
 
//Sign in
func (this *AuthorizeController) Login() {
	var user Model.LoginModel
    // Url? Username = 111 & password = 222
	user.UserName = this.GetString("username")
	user.PassWord = this.GetString("password")
 
    //Er: = this. ParseForm (& user) // Receive application/x-www-form-urlencoded POST transfer data, such as Username = 111 & Password = 2222
    // Er: = json. NewDecoder (this. Ctx. Request. Body). Decode (& user) // / Receives data in JSON form Post
 
	loginuser := &Model.Usertable{Userloginname: user.UserName}
	has, err := engine.Get(loginuser)
	if err != nil {
		fatal(err)
	}
	if !has {
		fatal(err)
		http.Error(this.Ctx.ResponseWriter, "User Not Exist", http.StatusBadRequest)
		return
	}
 
	if user.PassWord != loginuser.Userloginpwd {
		this.Ctx.Output.Header("SetStatus", strconv.Itoa(http.StatusBadRequest))
 
		http.Error(this.Ctx.ResponseWriter, "Password Wrong", http.StatusBadRequest)
		return
	}
 
	claims := make(jwt.MapClaims)
	claims["exp"] = time.Now().Add(time.Hour * time.Duration(1)).Unix()
	claims["iat"] = time.Now().Unix()
	claims["nameid"] = loginuser.Userloginname
	claims["User"] = "true"
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
 
	tokenString, err := token.SignedString([]byte(beego.AppConfig.String("jwtkey")))
	if err != nil {
		this.Ctx.Output.Header("SetStatus", strconv.Itoa(http.StatusInternalServerError))
		fatal(err)
		http.Error(this.Ctx.ResponseWriter, "Server is Wrong", http.StatusInternalServerError)
		return
	}
 
	fmt.Println("Token:", tokenString)
	this.Ctx.WriteString(fmt.Sprintf("{\"Token\":\"%s\"}", tokenString))
}
 
 
func (this *AuthorizeController) Userinfo() {
	token := this.Ctx.Input.Header("Authorization")
 
	b, t := CheckToken(token)
	if !b {
		this.Ctx.WriteString(fmt.Sprintf("Error:%s", token))
		return
	}
	loginuser := &Model.Usertable{Userloginname: claims["nameid"].(string)}
	has, err := engine.Get(loginuser)
	if err != nil {
		fatal(err)
	}
	if !has {
		fatal(err)
		http.Error(this.Ctx.ResponseWriter, "User Not Exist", http.StatusBadRequest)
		return
	}
	data, err := json.Marshal(loginuser)
	if err != nil {
		fmt.Println(err)
	}
	this.Ctx.WriteString(fmt.Sprintf("{\"Token\":\"%s\",\"User\":%s}", token, string(data)))
}
 
// Check whether token is valid
func CheckToken(token string) (b bool, t *jwt.Token) {
	kv := strings.Split(token, " ")
	if len(kv) != 2 || kv[0] != "Bearer" {
		beego.Error("AuthString invalid:", token)
		return false, nil
	}
	t, err := jwt.Parse(kv[1], func(*jwt.Token) (interface{}, error) {
		return []byte(beego.AppConfig.String("jwtkey")), nil
	})
	fmt.Println(t)
	if err != nil {
		fmt.Println("Convert to jwt claims fail.", err)
		return false, nil
	}
	return true, t
}

Structure of LoginModel.go submitting login username and password

package Model
 
type LoginModel struct {
	UserName string `xorm:"VARCHAR(50)"`
	PassWord string `xorm:"VARCHAR(50)"`
}

UserTable.go User Information Entity Structure

package Model
 
type Usertable struct {
	Userid        int    `xorm:"not null pk INT(4)"`
	Userloginname string `xorm:"VARCHAR(50)"`
	Userloginpwd  string `xorm:"VARCHAR(50)"`
	Username      string `xorm:"NVARCHAR(200)"`
	Usermobile    string `xorm:"VARCHAR(11)"`
	Userislock    int    `xorm:"BIT(1)"`
}

Start http web services through beego in main.go

package main
 
import (
	"GoApi/controller"
	"github.com/astaxie/beego"
)
 
func main() {
	beego.AutoRouter(&controller.AuthorizeController{})
	beego.Run()
}

Next step

1. Learn how to intercept validation in the interceptor and pass a result value to the interface to be accessed (currently, to parse jwt token once again in the interface)

2. How beego implements an interface that allows only post access to a controller (in AutoRouter mode)

3. How does Struct implement the Chinese description (that is, the Chinese description will be displayed when the mouse is placed, similar to the description of C#)

Posted by mrchuckles2002 on Sat, 19 Jan 2019 09:36:12 -0800