Golang身份验证。解析JWT:输入字节0处的非法base64数据。

huangapple go评论76阅读模式
英文:

Golang auth. Parsing JWT: illegal base64 data at input byte 0

问题

我正在为我的 Web 应用程序制作一个身份验证表单。

首先,我将表单数据发送到服务器,服务器生成令牌并将其存储在本地存储中。

然后,我想从表单页面重定向到主页。以下是将令牌发送到服务器的 JavaScript 代码,以便在主页上被视为已授权用户:

const xhr = new XMLHttpRequest()
xhr.open('GET', '/')
xhr.setRequestHeader('Authorization', localStorage.token)
xhr.send()
xhr.onload  = () => {
if(xhr.status >= 400) {
    console.log("error")
  }
}

xhr.onerror = () => {
    console.log("error")
}

然后,我想检查令牌并显示主页。以下是用于此目的的 Golang 函数:

func (h *Handler) Home_page(c *gin.Context) {
header := c.GetHeader("Authorization")
	if header != "" {
		_, err := h.services.Authorization.ParseToken(header)
		if err != nil {
			newErrorResponse(c, http.StatusUnauthorized, err.Error())
			return
		}
		c.HTML(
			http.StatusOK,
			"home_page.gohtml",
			gin.H{
				"IsAuth": true,
			},
		)
		return
	}
}

ParseToken 函数:

func (s *AuthService) ParseToken(accessToken string) (int, error) {
	token, err := jwt.ParseWithClaims(accessToken, &tokenClaims{}, func(token *jwt.Token) (interface{}, error) {
		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, errors.New("invalid signing method")
		}
		return []byte(signingKey), nil // signingKey 是一个带有随机元素的字符串
	})
	if err != nil {
		return 0, err
	}

	claims, ok := token.Claims.(*tokenClaims)
	if !ok {
		return 0, errors.New("token claims are not of type *tokenClaims")
	}

	return claims.UserId, nil
}

问题是我收到了这个错误:

ERRO[0001] illegal base64 data at input byte 0

我已经在 jwt.io 上检查了令牌,显示令牌已验证,可能问题在于我传递的字符串类型作为令牌。

另一个问题是,如果我不检查令牌验证返回的错误,主页将不显示,并显示以下错误:

http: panic serving [::1]:50490: write tcp [::1]:8083->[::1]:50490: write: broken pipe

我是 Golang 的新手,一直在解决这个问题,尽管它似乎很典型。

非常感谢您对如何处理令牌或从身份验证表单重定向的任何帮助!

英文:

I am making an authentication form on my web app.

First, I send the form data to server, it produces the token and I store it in the localStorage

Then, I want to redirect from form page to the home page. Here is the JavaScript that sends the token to server so that I would be seen as an authorized user on the home page:

const xhr = new XMLHttpRequest()
xhr.open('GET', '/')
xhr.setRequestHeader('Authorization', localStorage.token)
xhr.send()
xhr.onload  = () => {
if(xhr.status >= 400) {
    console.log("error")
  }
}

xhr.onerror = () => {
    console.log("error")
}

Then I want to check the token and show the home page. Here is the Golang func for it:

func (h *Handler) Home_page(c *gin.Context) {
header := c.GetHeader("Authorization")
	if header != "" {
		_, err := h.services.Authorization.ParseToken(header)
		if err != nil {
			newErrorResponse(c, http.StatusUnauthorized, err.Error())
			return
		}
		c.HTML(
			http.StatusOK,
			"home_page.gohtml",
			gin.H{
				"IsAuth": true,
			},
		)
		return
	}
}

ParseToken func:


func (s *AuthService) ParseToken(accessToken string) (int, error) {
	token, err := jwt.ParseWithClaims(accessToken, &tokenClaims{}, func(token *jwt.Token) (interface{}, error) {
		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, errors.New("invalid signing method")
		}
		return []byte(signingKey), nil //signingKey is a string with random elements
	})
	if err != nil {
		return 0, err
	}

	claims, ok := token.Claims.(*tokenClaims)
	if !ok {
		return 0, errors.New("token claims are not of type *tokenClaims")
	}

	return claims.UserId, nil
}

The problem is that I get this error:

ERRO[0001] illegal base64 data at input byte 0

I already checked the token on the jwt.io, it shows that the token is verified, maybe the problem is in the type of string that I am passing as a token.

Another problem is that if I don't check the error returning from token validation, the home page doesn't show with this error:

http: panic serving [::1]:50490: write tcp [::1]:8083->[::1]:50490: write: broken pipe

<br>
I am new to Golang, was struggling with this problem, though it seems typical.

I would be very thankful for any help on how to process the token or to redirect from the authentication form!

<br>

Edit: I am using the https://github.com/golang-jwt/jwt/v4

答案1

得分: 1

不知何故,这个问题:“输入字节0处的非法base64数据”通过改变我存储令牌的方式得到了解决。我之前是这样将令牌存储在本地存储中的:

localStorage.setItem('token', data.token)

我将其改为下一行,错误消失了:

localStorage.token = data.token

(data是服务器返回的带有令牌的JSON)

现在,如果我记录令牌的值,它将不带逗号显示。@Crowman,谢谢你的回答!

编辑:第二个问题是由于我在客户端没有等待答案导致的。所以现在我改变了JS代码以等待响应,但我仍然在努力使用JavaScript显示从服务器接收到的HTML页面。

英文:

Somehow, this issue:
illegal base64 data at input byte 0

Was solved by changing the way I stored the token. I was storing in the local storage like this:


localStorage.setItem(&#39;token&#39;, data.token)

I changed it to the next line and the error disappeared:

localStorage.token = data.token

(data is the JSON with token that my server returns)

Now if I log the value of token it appears without commas. @Crowman, thank you for answer!

Edit: The second issue with broken pipe occurred, because I was not waiting for the answer on the client side. So now I changed the JS code to wait for the response but still I am struggling with how to show the html page that I receive from server using JavaScript.

huangapple
  • 本文由 发表于 2022年1月8日 00:15:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/70624166.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定