更新更新滑进,節(jié)前沒事,摸摸魚,敲敲代碼蔑担,就很舒服了。
用戶權(quán)限
先抄抄大佬怎么寫的
使用JWT進(jìn)行認(rèn)證
用戶注冊之后, 服務(wù)器生成一個 JWT token返回給瀏覽器, 瀏覽器向服務(wù)器請求數(shù)據(jù)時將 JWT token 發(fā)給服務(wù)器, 服務(wù)器用 signature 中定義的方式解碼
JWT 獲取用戶信息.
一個 JWT token包含3部分:
- header: 告訴我們使用的算法和 token 類型
- Payload: 必須使用 sub key 來指定用戶 ID, 還可以包括其他信息比如 email, username 等.
- Signature: 用來保證 JWT 的真實性. 可以使用不同算法
所以先來寫一下登陸方法
1.先獲取請求內(nèi)容
2.去數(shù)據(jù)庫驗證
3.生成JWT
4.將JWT字符串作為該請求Cookie的一部分返回給用戶咽白。注意啤握,在這里必須使用HttpOnly
屬性來防止Cookie被JavaScript讀取,從而避免跨站腳本攻擊(XSS攻擊)
5.在Cookie失效或者被刪除前晶框,用戶每次訪問應(yīng)用排抬,應(yīng)用都會接受到含有jwt的Cookie。從而應(yīng)用就可以將JWT從請求中提取出來授段。
6.應(yīng)用通過一系列任務(wù)檢查JWT的有效性蹲蒲。例如,檢查簽名是否正確侵贵;檢查Token是否過期届搁;檢查Token的接收方是否是自己(可選)。
7.應(yīng)用在確認(rèn)JWT有效之后模燥,JWT進(jìn)行Base64解碼(可能在上一步中已經(jīng)完成)咖祭,然后在Payload中讀取用戶的id值,也就是user_id屬性蔫骂。
8.應(yīng)用從數(shù)據(jù)庫取到用戶的信息么翰,加載到內(nèi)存中,進(jìn)行ORM之類的一系列底層邏輯初始化辽旋。
9.應(yīng)用根據(jù)用戶請求進(jìn)行響應(yīng)
//userlogin.go
package Controller
import (
"encoding/json"
"fmt"
"net/http"
"strings"
"time"
"ginMall/Helper"
"ginMall/Helper/Constant"
jwt "github.com/dgrijalva/jwt-go"
"github.com/gin-gonic/gin"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
type UserCredentials struct {
Username string `json:"username"`
Password string `json:"password"`
//驗證碼從前端判斷就行了
}
type Token struct {
Token string `json:"token"`
}
//用戶注冊之后, 服務(wù)器生成一個 JWT token返回給瀏覽器, 瀏覽器向服務(wù)器請求數(shù)據(jù)時將 JWT token 發(fā)給服務(wù)器, 服務(wù)器用 signature 中定義的方式解碼
//JWT 獲取用戶信息.
func Login(c *gin.Context) {
//1.獲取請求內(nèi)容
var user UserCredentials
err := json.NewDecoder(c.Request.Body).Decode(&user)
if err != nil {
c.Writer.WriteHeader(http.StatusForbidden)
fmt.Fprint(c.Writer, "Error in request")
return
}
//2.去數(shù)據(jù)庫驗證
if strings.ToLower(user.Username) != "我" {
if user.Password != "密碼" {
c.Writer.WriteHeader(http.StatusForbidden)
fmt.Println("Error logging in")
fmt.Fprint(c.Writer, "Invalid credentials")
return
}
}
//3.生成JWT
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(Constant.CONST_SECRET_KEY))
if err != nil {
c.Writer.WriteHeader(http.StatusInternalServerError)
fmt.Fprintln(c.Writer, "Error while signing the token")
}
response := Token{tokenString}
//4.將JWT字符串作為該請求Cookie的一部分返回給用戶
Helper.JsonResponse(response, w)
}
//InterceptHelper.go
package Helper
import (
"fmt"
"ginMall/Helper/Constant"
"net/http"
jwt "github.com/dgrijalva/jwt-go"
"github.com/dgrijalva/jwt-go/request"
"github.com/gin-gonic/gin"
)
func IsLogin(c *gin.Context) {
//5.在Cookie失效或者被刪除前浩嫌,用戶每次訪問應(yīng)用檐迟,應(yīng)用都會接受到含有jwt的Cookie。
token, err := request.ParseFromRequest(c.Request, request.AuthorizationHeaderExtractor,
//6.應(yīng)用通過一系列任務(wù)檢查JWT的有效性
func(token *jwt.Token) (interface{}, error) {
//7.應(yīng)用在確認(rèn)JWT有效之后码耐,JWT進(jìn)行Base64解碼
return []byte(Constant.CONST_SECRET_KEY), nil
})
if err == nil {
if token.Valid {
//7.讀取用戶的id值
//8.應(yīng)用從數(shù)據(jù)庫取到用戶的信息追迟,加載到內(nèi)存中,進(jìn)行ORM之類的一系列底層邏輯初始化骚腥。
//9.應(yīng)用根據(jù)用戶請求進(jìn)行響應(yīng)
//next(c.Writer, c.Request)
} else {
c.Writer.WriteHeader(http.StatusUnauthorized)
fmt.Fprint(c.Writer, "Token is not valid")
}
} else {
c.Writer.WriteHeader(http.StatusUnauthorized)
fmt.Fprint(c.Writer, "Unauthorized access to this resource")
}
}