---
# System prepended metadata

title: Gin帳密Auth MiddleWare

---

# 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';         
        }
```