jwt认证就是用户注册之后, 服务器生成一个 JWT token返回给浏览器, 浏览器向服务器请求数据时将 JWT token 发给服务器, 服务器用 signature 中定义的方式解码 。
安装:go get github.com/dgrijalva/jwt-go
go get github.com/dgrijalva/jwt-go/request
main.go
package main
import (
"data"
"fmt"
"net/http"
"github.com/dgrijalva/jwt-go"
"github.com/dgrijalva/jwt-go/request"
"gopkg.in/gin-gonic/gin.v1"
)
func main() {
router := gin.Default()
router.POST("/customer/register", data.Register)
router.POST("/login", data.Login)
//添加群组中间件
authorized := router.Group("/user", MyMiddelware())
authorized.POST("/info", func(c *gin.Context) {
c.String(http.StatusOK, "info")
})
router.Run(":8080")
}
func MyMiddelware() gin.HandlerFunc {
return func(c *gin.Context) {
token, err := request.ParseFromRequest(c.Request, request.AuthorizationHeaderExtractor,
func(token *jwt.Token) (interface{}, error) {
return []byte("mobile"), nil
})
if err == nil {
if token.Valid {
c.Next()
} else {
c.String(http.StatusUnauthorized, "Token is not valid")
}
} else {
c.String(http.StatusUnauthorized, "Unauthorized access to this resource")
}
}
}
data.go
package data
import (
"encoding/json"
"fmt"
"net/http"
"gopkg.in/gin-gonic/gin.v1"
_ "github.com/go-sql-driver/mysql"
"github.com/go-xorm/xorm"
)
var Db *xorm.Engine
func init() {
var err error
//打开数据库
//DSN数据源字符串:用户名:密码@协议(地址:端口)/数据库?参数=参数值
Db, err = xorm.NewEngine("mysql", "yuanye:yuanye@tcp(127.0.0.1:3306)/wemai?charset=utf8")
if err != nil {
fmt.Println(err)
}
Db.ShowSQL(true)
err = Db.Sync2(new(Customer), new(Goods), new(CustomerInfo))
}
func JsonResponse(code int, data interface{}) string {
response := make(map[string]interface{})
response["code"] = code
response["data"] = data
js, err := json.Marshal(response)
if err != nil {
return err.Error()
}
return string(js)
}
func Register(c *gin.Context) {
username := c.PostForm("username")
password := c.PostForm("password")
user := Customer{
Username: username,
Password: password,
}
c.String(http.StatusOK, user.Register())
}
func Login(c *gin.Context) {
username := c.PostForm("username")
password := c.PostForm("password")
user := Customer{
Username: username,
Password: password,
}
c.String(http.StatusOK, user.Login())
}
Customer.go
package data
import (
"time"
"github.com/dgrijalva/jwt-go"
)
type Customer struct {
Id int `xorm:"pk autoincr"`
Username string `xorm:"index unique notnull"`
Password string `xorm:"notnull"`
CreatedAt time.Time `xorm:"created"`
}
func (c *Customer) Register() string {
Db.Insert(c)
has, _ := Db.Get(c)
if has {
return JsonResponse(0, "注册成功")
} else {
return JsonResponse(1, "注册失败")
}
}
func (c *Customer) Login() string {
has, _ := Db.Get(c)
if has {
return JsonResponse(0, setToken())
} else {
return JsonResponse(1, "登录失败")
}
}
func setToken() string {
token := jwt.New(jwt.SigningMethodHS256)
claims := make(jwt.MapClaims)
claims["exp"] = time.Now().Add(time.Hour * time.Duration(1)).Unix()
claims["iat"] = time.Now().Unix()
token.Claims = claims
tokenString, err := token.SignedString([]byte("mobile"))
if err != nil {
return ""
}
return tokenString
}
代码结构
运行效果:
登录失败时的效果:
登录成功,返回token
带token请求user/info接口
当不带token时,返回错误信息