如何用JavaScript检查Go Gin中间件生成的AccessToken并控制UI按钮
解决方案
一、把AccessToken传递给前端
首先需要修改登录接口,将生成的AccessToken传递到前端,常用两种实现方式:
1. 通过Cookie传递(推荐,安全性更高)
修改loginUser函数,登录成功生成token后,设置Cookie存储:
func loginUser(c *gin.Context) { // 原有登录逻辑,生成accessToken accessToken, err := tokenMaker.CreateToken(username, duration) if err != nil { c.AbortWithStatusJSON(http.StatusInternalServerError, errorResponse(err)) return } // 设置Cookie:若允许JS读取则关闭httpOnly;若仅后端使用则开启httpOnly=true c.SetCookie("access_token", accessToken, int(duration.Seconds()), "/", "", false, false) c.Next() }
2. 通过模板注入(服务器端渲染场景)
在登录成功返回HTML时,将token注入模板变量,再存入前端全局变量:
修改登录后的HTML渲染逻辑:
router.POST("/login", server.loginUser, func(c *gin.Context) { accessToken, _ := c.Get("access_token") // 假设loginUser将token存入context c.HTML(http.StatusOK, "index.html", gin.H{ "title": "Главная страница", "access_token": accessToken, }) })
在index.html模板中注入全局变量:
<script> // 方式1:存入全局变量 window.accessToken = "{{.access_token}}"; // 方式2:存入localStorage localStorage.setItem("access_token", "{{.access_token}}"); </script>
二、用JavaScript检查用户授权
有两种可靠的检查方式,可根据场景选择:
1. 检查本地存储的Token
页面加载时直接读取Cookie或localStorage中的token,判断授权状态:
// 从Cookie获取token的工具函数 function getCookie(name) { let value = "; " + document.cookie; let parts = value.split("; " + name + "="); if (parts.length === 2) return parts.pop().split(";").shift(); } // 检查授权状态并更新UI function checkAuth() { const token = getCookie("access_token") || localStorage.getItem("access_token"); if (!token) { // 未授权:隐藏需权限的按钮,显示游客按钮 document.getElementById("auth-only-buttons").style.display = "none"; document.getElementById("guest-buttons").style.display = "block"; return; } // 已授权:显示权限按钮,隐藏游客按钮 document.getElementById("auth-only-buttons").style.display = "block"; document.getElementById("guest-buttons").style.display = "none"; } // 页面加载完成后执行检查 window.addEventListener("DOMContentLoaded", checkAuth);
2. 调用后端验证接口(更严谨)
后端新增一个受authMiddleware保护的验证接口,返回用户授权状态:
authRoutes.GET("/verify", func(c *gin.Context) { payload, exists := c.Get(authorizationPayloadKey) if !exists { c.AbortWithStatusJSON(http.StatusUnauthorized, errorResponse(errors.New("无效token"))) return } c.JSON(http.StatusOK, gin.H{ "authorized": true, "username": payload.(*token.Payload).Username, }) })
前端通过AJAX调用该接口验证:
async function checkAuth() { const token = getCookie("access_token") || localStorage.getItem("access_token"); if (!token) { updateUI(false); return; } try { const response = await fetch("/verify", { headers: { "Authorization": `Bearer ${token}` } }); if (response.ok) { const data = await response.json(); updateUI(true, data.username); } else { updateUI(false); } } catch (err) { updateUI(false); } } function updateUI(isAuthorized, username) { const authButtons = document.getElementById("auth-only-buttons"); const guestButtons = document.getElementById("guest-buttons"); const usernameDisplay = document.getElementById("username-display"); if (isAuthorized) { authButtons.style.display = "block"; guestButtons.style.display = "none"; usernameDisplay.textContent = `欢迎, ${username}`; } else { authButtons.style.display = "none"; guestButtons.style.display = "block"; usernameDisplay.textContent = ""; } } window.addEventListener("DOMContentLoaded", checkAuth);
三、调用时机与UI实现细节
- 调用时机:页面加载完成时执行检查;登录/登出操作完成后,重新调用
checkAuth()更新UI。 - UI结构示例:提前在HTML中区分授权/游客状态的按钮组:
<!-- 游客状态按钮 --> <div id="guest-buttons"> <a href="/login">登录</a> <a href="/users">注册</a> </div> <!-- 授权状态按钮(默认隐藏) --> <div id="auth-only-buttons" style="display: none;"> <a href="/account/{{.username}}">个人中心</a> <button onclick="logout()">退出登录</button> <span id="username-display"></span> </div>
- 登出逻辑:清除存储的token并刷新页面:
function logout() { // 清除Cookie document.cookie = "access_token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;"; // 清除localStorage localStorage.removeItem("access_token"); // 刷新页面 window.location.reload(); }
内容的提问来源于stack exchange,提问作者pizhlo
相关产品推荐
相关产品推荐

