You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 20:53:19