# Gin帳密Auth MiddleWare
## 簡介
> 從Gin原碼 "BasicAuth" 參考改寫的
> 把帳密寫死在程式碼的方式,改成從資料庫搜尋
## 重新寫個MiddleWare
```go=
func SqlAuth(c *gin.Context) {
realm := "Authorization Required"
realm = "Basic realm=" + strconv.Quote(realm)
// 取得輸入的帳密
getAuthReq := c.Request.Header.Get("Authorization")
startEncode := strings.Index(getAuthReq, " ")
// 先從base64 decode 回來
res, errDecode := base64.StdEncoding.DecodeString(getAuthReq[startEncode+1:])
if errDecode != nil {
log.Println("Fail to Decode: ", errDecode)
c.Header("WWW-Authenticate", realm)
c.AbortWithStatus(http.StatusUnauthorized)
return
}
userAndPasswd := string(res)
// 其格式為 user:password
userIndex := strings.Index(userAndPasswd, ":")
username := userAndPasswd[:userIndex]
password := userAndPasswd[userIndex+1:]
// SQL 查詢,這邊還未HASH password
user, found := models.FindAuthUser(username, password)
if !found {
c.Header("WWW-Authenticate", realm)
c.AbortWithStatus(http.StatusUnauthorized)
return
}
c.Set(gin.AuthUserKey, user)
}
```
## 加入到gin中
```go=
func main(){
r := gin.Default()
backAuth := r.Group("/auth", auth.SqlAuth)
backAuth.GET("/test", func(c *gin.Context) {
user := c.MustGet(gin.AuthUserKey).(string)
if user != ""{
c.JSON(http.StatusOK, gin.H{
"result": "ok",
"user" : user,
})
} else {
c.JSON(http.StatusOK, gin.H{
"result": "fail",
})
}
})
}
```
## ~~前端JavaScript轉址並傳遞Auth~~
```javascript=
function login() {
const username = $("#username").val();
const password = $("#password").val();
const encoded = btoa(username + ':' + password);
window.location.href =
window.location.protocol + "//" +
username + ":" + password + "@" +
window.location.hostname +
(window.location.port ? ":" + window.location.port : "") +
'/auth/test';
}
```