okta access token 用户登录一小时后失效,如何延迟避免用户频发登录,保存在哪里,前端Vue 实现,后端是golang ; 提供一个方案

okta access token 用户登录一小时后失效,如何延迟避免用户频发登录,保存在哪里,前端Vue 实现,后端是golang ; 提供一个方案

ChatGPT said:

非常好的问题 👍 你提到的场景(Okta access token 登录 1 小时后失效 )是非常常见的,尤其是前后端分离架构中。下面给出一个完整可落地的方案,包括 前端(Vue)后端(Golang) 的设计思路。


✅ 一、问题背景

  • Access Token(访问令牌) :有效期较短(例如 1 小时),用于访问受保护的资源(API)。
  • Refresh Token(刷新令牌) :有效期较长(例如 30 天),用于在 Access Token 过期时获取新的 Access Token。
  • 问题:如果只使用 Access Token,用户登录一小时后就得重新登录。

✅ 二、解决方案:Access Token + Refresh Token 双令牌机制

核心思路:

  1. 登录时,后端从 Okta 获取 access_tokenrefresh_token
  2. 前端只保存 access_token(短期),refresh_token 存在 HttpOnly Cookie
  3. 当 access token 过期时,前端调用 /auth/refresh 接口;
  4. 后端使用 refresh_token 向 Okta 换取新的 access_token
  5. 刷新成功后更新 Cookie 和前端存储。

✅ 三、后端(Golang)实现方案

1️⃣ 登录阶段

go 复制代码
// /auth/login
func (h *Handler) Login(c *gin.Context) {
    var req struct {
        Username string `json:"username"`
        Password string `json:"password"`
    }
    if err := c.ShouldBindJSON(&req); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request"})
        return
    }

    // 向 Okta 请求 token
    tokenResp, err := getTokenFromOkta(req.Username, req.Password)
    if err != nil {
        c.JSON(http.StatusUnauthorized, gin.H{"error": "invalid credentials"})
        return
    }

    // 设置 refresh_token 到 HttpOnly Cookie
    http.SetCookie(c.Writer, &http.Cookie{
        Name:     "refresh_token",
        Value:    tokenResp.RefreshToken,
        Path:     "/",
        HttpOnly: true,
        Secure:   true,
        SameSite: http.SameSiteLaxMode,
        MaxAge:   60 * 60 * 24 * 30, // 30天
    })

    // 返回 access_token 给前端
    c.JSON(http.StatusOK, gin.H{
        "access_token": tokenResp.AccessToken,
        "expires_in":   tokenResp.ExpiresIn,
    })
}

2️⃣ 刷新阶段

php 复制代码
// /auth/refresh
func (h *Handler) Refresh(c *gin.Context) {
    cookie, err := c.Request.Cookie("refresh_token")
    if err != nil {
        c.JSON(http.StatusUnauthorized, gin.H{"error": "no refresh token"})
        return
    }

    // 向 Okta 用 refresh token 换取新 access token
    newTokenResp, err := refreshTokenFromOkta(cookie.Value)
    if err != nil {
        c.JSON(http.StatusUnauthorized, gin.H{"error": "invalid refresh token"})
        return
    }

    // 更新 Cookie(新的 refresh_token)
    http.SetCookie(c.Writer, &http.Cookie{
        Name:     "refresh_token",
        Value:    newTokenResp.RefreshToken,
        Path:     "/",
        HttpOnly: true,
        Secure:   true,
        SameSite: http.SameSiteLaxMode,
        MaxAge:   60 * 60 * 24 * 30,
    })

    // 返回新的 access token
    c.JSON(http.StatusOK, gin.H{
        "access_token": newTokenResp.AccessToken,
        "expires_in":   newTokenResp.ExpiresIn,
    })
}

🔐 注意:refresh_token 绝不能返回给前端!必须存在 Cookie 中,并开启 HttpOnlySecure


✅ 四、前端(Vue)实现方案

1️⃣ 登录后保存 token

javascript 复制代码
// 登录后
axios.post('/auth/login', { username, password }).then(res => {
  localStorage.setItem('access_token', res.data.access_token);
  localStorage.setItem('token_expiry', Date.now() + res.data.expires_in * 1000);
});

2️⃣ Axios 拦截器自动刷新

javascript 复制代码
import axios from 'axios';

const api = axios.create({
  baseURL: '/api',
});

// 请求拦截器
api.interceptors.request.use(async config => {
  const accessToken = localStorage.getItem('access_token');
  const expiry = localStorage.getItem('token_expiry');

  // 如果 token 过期了,自动刷新
  if (Date.now() > expiry - 30 * 1000) { // 提前30秒刷新
    try {
      const res = await axios.post('/auth/refresh', {}, { withCredentials: true });
      localStorage.setItem('access_token', res.data.access_token);
      localStorage.setItem('token_expiry', Date.now() + res.data.expires_in * 1000);
      config.headers.Authorization = `Bearer ${res.data.access_token}`;
    } catch (err) {
      // refresh token 也失效,跳转登录
      window.location.href = '/login';
      throw err;
    }
  } else {
    config.headers.Authorization = `Bearer ${accessToken}`;
  }

  return config;
});

export default api;

3️⃣ 登录状态持久化

  • access_token 保存在 localStorage
  • refresh_token 由后端存入 Cookie;
  • 刷新时,浏览器会自动带上 Cookie(withCredentials: true)。

✅ 五、Token 生命周期建议

Token 类型 有效期 存储位置 安全性 用途
Access Token 1 小时 localStorage ✅ 中 API 调用
Refresh Token 30 天 HttpOnly Cookie ✅ 高 刷新 access token

✅ 六、总结方案结构

javascript 复制代码
+----------------------+           +----------------------+
|       Vue 前端       |  <----->  |     Golang 后端     |
|----------------------|           |----------------------|
| localStorage:        |           | /auth/login          |
|  - access_token      |  登录 ->  | /auth/refresh        |
| Cookie: refresh_token|  刷新 ->  | 与 Okta 通信         |
+----------------------+           +----------------------+

✅ 七、补充建议

  • 后端可加入 token 缓存机制,减少频繁访问 Okta;
  • 若系统需要多端登录,可为每个 refresh token 绑定 session_id
  • 若有 SSO 需求,可使用 Okta 的 Session Token + Silent Refresh 流程。

是否希望我帮你补一份完整的 Vue + Go 最小可运行示例(包含登录、自动刷新和退出逻辑)?

You said:

Cookie: refresh_token| 这样有风险吗

ChatGPT said:

非常好的问题,这个是实现中最关键的安全点 之一。

我们来详细分析:把 refresh_token 存在 Cookie(尤其是 HttpOnly Cookie)是否安全、风险在哪、怎么降低风险。


✅ 一、结论先说:

refresh_token 存在 HttpOnly + Secure Cookie 是当前最佳实践之一

前提是你必须正确配置这些安全属性。

它是 OAuth 2.0 + OpenID Connect 推荐的安全实现方式之一(包括 Okta 官方、Auth0、Google 都是这么做的)。


✅ 二、为什么要放在 Cookie(而不是 localStorage)

存储位置 优点 风险 推荐程度
localStorage 前端可读可写,方便使用 容易被 XSS 窃取(因为 JS 可访问) ❌ 不推荐存 refresh_token
HttpOnly Cookie 前端 JS 无法访问 若配置不当,可能被 CSRF 利用 ✅ 推荐(配合防御手段)

总结一句话

localStorage 容易被偷,HttpOnly Cookie 不容易被偷,但可能被滥用(CSRF)。


✅ 三、潜在风险与防护措施

⚠️ 风险1:CSRF(跨站请求伪造)

攻击者伪造请求访问 /auth/refresh,利用用户浏览器自动携带 Cookie 来换取新 token。

🔒 解决方案:

  1. 使用 SameSite 属性:

    php 复制代码
    http.SetCookie(w, &http.Cookie{
        Name:     "refresh_token",
        Value:    token,
        Path:     "/",
        HttpOnly: true,
        Secure:   true,                   // 仅 HTTPS
        SameSite: http.SameSiteStrictMode, // 或 LaxMode
    })
    • SameSite=Strict:最安全,跨站点不带 Cookie;
    • SameSite=Lax:允许来自同站导航;
    • None:仅当必须支持跨域登录才使用,且必须配合 Secure=true
  2. 刷新接口要求额外身份信息

    • 例如要求 X-Client-IdOrigin 校验;
    • 或要求前端携带一个一次性防伪 Token(CSRF Token)。

⚠️ 风险2:Cookie 被盗(中间人攻击)

如果用户访问 HTTP 页面,Cookie 可能被截获。

🔒 解决方案:

  • 强制全站 HTTPS
  • Cookie 设置 Secure: true
  • 如果可能,启用 HSTS(HTTP Strict Transport Security)。

⚠️ 风险3:Refresh Token 长期有效

被盗后可长期换取 Access Token。

🔒 解决方案:

  • 让 Okta 的 refresh_token 设置为 一次性刷新(Rotating Refresh Token)
  • 每次刷新时 Okta 返回新的 refresh token;
  • 后端更新 Cookie;
  • 旧的 refresh token 自动失效。

Okta 支持此机制,可在 Okta 的 OAuth Application 设置中启用。


✅ 四、最佳安全配置汇总

安全项 是否启用 说明
HttpOnly 禁止前端 JS 访问
Secure 仅 HTTPS 传输
SameSite 推荐 StrictLax
Rotating Refresh Token 每次刷新生成新的 refresh_token
Access Token 短期有效 减少滥用时间窗口
后端刷新接口防伪验证 增加安全性

✅ 五、总结一句话

refresh_token 存在 HttpOnly + Secure + SameSite Cookie 中,是安全且推荐的方式

远比放在 localStorage、sessionStorage 或 Vuex 中安全得多。


如果你希望我帮你写出一段完整的安全 Cookie 设置 + refresh 接口示例(Go 代码) ,我可以直接给你复制可用的一份。

是否要我帮你写?

You said:

// 登录后 axios.post('/auth/login', { username, password }).then(res => { localStorage.setItem('access_token', res.data.access_token); localStorage.setItem('token_expiry', Date.now() + res.data.expires_in * 1000); }) 这样有没有风险

ChatGPT said:

非常好的追问 👏

你提到的这段代码是典型的前端登录后存储 access_token 的方式:

javascript 复制代码
axios.post('/auth/login', { username, password }).then(res => {
  localStorage.setItem('access_token', res.data.access_token);
  localStorage.setItem('token_expiry', Date.now() + res.data.expires_in * 1000);
});

这个方案能用,但有安全风险,我们可以详细分解一下。


✅ 一、结论先说

⚠️ 把 access_token 存在 localStorage有风险的 ,但在某些受控环境下可以接受。

✅ 更安全的方式是存在 内存(JS 变量)短期 sessionStorage ,配合 HttpOnly Cookie 存放 refresh_token


✅ 二、为什么有风险

⚠️ 1. XSS 攻击风险

localStorage浏览器 JS 可读写的持久存储

如果你的网站存在任何 XSS 漏洞(例如有人能注入一段 <script>),攻击者就能执行:

javascript 复制代码
console.log(localStorage.getItem('access_token'))

然后把它发到远程服务器。

⛔ 一旦被盗,攻击者可以在一小时内冒充用户访问你的 API。


⚠️ 2. Token 永久存在(除非手动清除)

localStorage 是持久的,即使用户关闭浏览器,下次打开仍存在。

如果用户使用的是公共电脑共享设备、或者电脑被入侵,就可能被盗。


✅ 三、可接受的场景

如果满足以下条件,可以暂时使用 localStorage

  1. 你的前端是内部管理系统,不公开访问;

  2. 所有 API 都在同一域名(不跨域);

  3. 你在 HTTP 响应头里开启了:

    css 复制代码
    Content-Security-Policy: default-src 'self'; script-src 'self'

    (防止外部脚本注入);

  4. Access Token 本身是短期(例如 1 小时),并且配合 Refresh Token 定期更新。


✅ 四、更安全的替代方案

方案 安全性 持久性 描述
localStorage ❌ 容易被 XSS 读出 持久 当前实现方式
sessionStorage ⚠️ 关闭标签页后清空 短期 比 localStorage 稍安全
JS 内存变量(Vuex/pinia) ✅ 不可持久化,XSS 仍危险 临时 最安全,但刷新页面后需重新获取
HttpOnly Cookie ✅ 无法被 JS 访问 可持久 适合存 refresh_token

✅ 五、推荐组合(前后端配合)

项目 存放位置 有效期 说明
access_token JS 内存 / sessionStorage 1小时 每次刷新时更新
refresh_token HttpOnly Cookie 30天 仅服务器可读,防XSS

✅ 六、改进实现示例

1️⃣ 登录时

javascript 复制代码
axios.post('/auth/login', { username, password }, { withCredentials: true })
  .then(res => {
    sessionStorage.setItem('access_token', res.data.access_token);
    sessionStorage.setItem('token_expiry', Date.now() + res.data.expires_in * 1000);
  });

2️⃣ Axios 请求拦截器(自动刷新)

ini 复制代码
api.interceptors.request.use(async config => {
  const token = sessionStorage.getItem('access_token');
  const expiry = sessionStorage.getItem('token_expiry');

  if (Date.now() > expiry - 30 * 1000) {
    const res = await axios.post('/auth/refresh', {}, { withCredentials: true });
    sessionStorage.setItem('access_token', res.data.access_token);
    sessionStorage.setItem('token_expiry', Date.now() + res.data.expires_in * 1000);
    config.headers.Authorization = `Bearer ${res.data.access_token}`;
  } else {
    config.headers.Authorization = `Bearer ${token}`;
  }

  return config;
});

✅ 七、防御建议汇总

风险 防御手段
XSS 窃取 token 严格 CSP、输入转义、避免 v-html
Refresh Token 被利用 使用 HttpOnly Cookie + SameSite
中间人攻击 HTTPS + HSTS
令牌泄漏后长期有效 短期 access_token + rotating refresh_token
第三方脚本注入 不引入外部脚本(或通过 Subresource Integrity 校验)

✅ 八、总结一句话

localStorageaccess_token 是可行但不安全;

推荐使用 sessionStorage 或内存 + 后端持有的 HttpOnly refresh_token 组合。

简单来说:

  • Access Token 短期,存在浏览器;
  • Refresh Token 长期,存在服务器 Cookie;
  • 定期刷新,永不暴露长期凭据。

是否希望我帮你画一个这套安全 Token 流程的图(前端 + 后端 + Okta 交互)?

(能一眼看清整个生命周期和交互安全点)

You said:

后端以及执行refresh 了,前端还需要 api.interceptors.request.use(async config => { const token = sessionStorage.getItem('access_token'); const expiry = sessionStorage.getItem('token_expiry'); if (Date.now() > expiry - 30 * 1000) { const res = await axios.post('/auth/refresh', {}, { withCredentials: true }); sessionStorage.setItem('access_token', res.data.access_token); sessionStorage.setItem('token_expiry', Date.now() + res.data.expires_in * 1000); config.headers.Authorization = Bearer ${res.data.access_token}; } else { config.headers.Authorization = Bearer ${token}; } return config; });

ChatGPT said:

非常好的问题 👍

你问得非常关键------

"后端已经执行了 refresh(自动刷新 access token),那前端还需要写这个 axios 拦截器逻辑吗?"


✅ 一、结论先说

要看后端"自动刷新"的策略在哪里执行:

  • 如果刷新逻辑在后端 API 层自动处理(前端始终拿到有效 token) → 前端可以不写。
  • 如果刷新逻辑需要前端主动触发 /auth/refresh 接口 → 前端拦截器是必须的。

✅ 二、两种常见架构对比

架构方式 刷新逻辑在哪 前端是否需要拦截器 说明
🧩 前端触发刷新 前端判断过期 → 调用 /auth/refresh ✅ 需要 常见于前后端分离(Vue + Go)
🧠 后端自动刷新 Go 后端在调用 Okta 时自动刷新 ❌ 不需要 适合 BFF 模式(后端代发 API 请求)

🔹 第一种:前后端分离(你目前的情况)

你现在的系统是:

  • Vue 前端 → 调用 Go 后端 API;
  • Go 后端再验证 Access Token。

如果前端直接带 Authorization: Bearer <access_token> 调用后端,

前端必须知道 access_token 什么时候过期,并在过期前自己刷新,否则请求会被拒绝(401)。

👉 所以这里前端的 axios 拦截器 是必须的,因为:

  • 后端不会主动替你刷新;
  • refresh_token 在 Cookie 里(前端看不到);
  • 前端通过 /auth/refresh 让后端去刷新。

📦 总结一句话:

前端是"提醒人",后端是"干活人"。


🔹 第二种:BFF(Backend for Frontend)模式

如果你的后端是这样工作的:

  1. 前端 不存 access_token
  2. 每个请求前端只发 session cookie;
  3. Go 后端拿到 session → 自动在服务器上调用 Okta API;
  4. 如果发现 token 过期 → 后端自己用 refresh_token 获取新 token;
  5. 前端完全无感知。

那这种模式下,前端不需要拦截器,因为前端根本不管 token。

📦 总结一句话:

后端全托管刷新逻辑,前端只发 Cookie。


✅ 三、你当前架构的推荐策略

你目前的系统结构(Vue 前端 + Go 后端 + Okta):

  • 前端持有 access_token
  • 后端只验证 token 或转发给 Okta
  • Refresh Token 放在后端 Cookie

👉 所以推荐:

后端提供 /auth/refresh 接口,负责实际刷新

前端保留 axios 拦截器,负责检测和触发刷新

前端不保存 refresh_token(仍由 Cookie 持有)


✅ 四、完整时序图(推荐方式)

scss 复制代码
用户登录
   │
   ▼
前端获取 access_token + refresh_token(HttpOnly Cookie)
   │
   ▼
前端带 Authorization 调用 API
   │
   ├── access_token 有效 → 正常响应
   │
   └── access_token 过期 →
           │
           ▼
        前端 axios 拦截器调用 /auth/refresh
           │
           ▼
        后端从 Cookie 拿 refresh_token
           │
           ▼
        向 Okta 换取新 access_token
           │
           ▼
        返回新 access_token 给前端
           │
           ▼
        前端更新 sessionStorage 后重试原请求

✅ 五、总结一句话

问题 答案
后端会刷新 token,那前端还需要拦截器吗? ✅ 需要(除非你是 BFF 架构)
为什么要拦截? 因为 access_token 在前端保存,前端必须知道何时刷新
如果是纯后端托管? ❌ 不需要,后端自动刷新即可
当前 Vue + Go 场景? ✅ 必须有拦截器,否则 access_token 过期后会 401

是否希望我帮你画一个对比图:

🧠「后端托管刷新(BFF)」 vs 🧩「前端触发刷新」的完整时序和差异?

(这样你能一眼看出哪种更适合你现在的系统结构)

You said:

给出完整的序列图

ChatGPT said:

非常好 👍

下面是一个对比性极强的说明:

我给你两张 完整序列图(时序图) ------

✅ 第一张:前端触发刷新(前后端分离模式,适合你目前 Vue + Go + Okta)

✅ 第二张:后端自动刷新(BFF 模式)

两者的安全性、复杂度和职责边界完全不同。


🧩 方案一:前端触发刷新(当前推荐方案)

这是你目前的架构(Vue 前端 + Go 后端 + Okta),最常见的做法。

sequenceDiagram participant User as 👤 用户 participant Vue as 🖥️ 前端(Vue) participant Go as 🧠 后端(Golang API) participant Okta as 🔐 Okta 授权服务器 User->>Vue: 输入用户名/密码点击登录 Vue->>Go: POST /auth/login {username, password} Go->>Okta: 授权请求,获取 access_token + refresh_token Okta-->>Go: 返回 tokens Go-->>Vue: 返回 access_token + 设置 Cookie(HttpOnly refresh_token) Vue->>Vue: 保存 access_token, token_expiry loop 每次调用API Vue->>Vue: 检查 token 是否即将过期 alt token 有效 Vue->>Go: GET /api/data (Bearer access_token) Go-->>Vue: 返回数据 else token 过期 Vue->>Go: POST /auth/refresh (携带 Cookie) Go->>Okta: 用 refresh_token 换新 access_token Okta-->>Go: 返回新 access_token + 新 refresh_token Go-->>Vue: 返回新的 access_token (Cookie 更新) Vue->>Vue: 更新 sessionStorage 中的 token Vue->>Go: 重试原请求 (Bearer new token) Go-->>Vue: 返回数据 end end
rust 复制代码
sequenceDiagram
    participant User as 👤 用户
    participant Vue as 🖥️ 前端(Vue)
    participant Go as 🧠 后端(Golang API)
    participant Okta as 🔐 Okta 授权服务器

    User->>Vue: 输入用户名/密码点击登录
    Vue->>Go: POST /auth/login {username, password}
    Go->>Okta: 授权请求,获取 access_token + refresh_token
    Okta-->>Go: 返回 tokens
    Go-->>Vue: 返回 access_token + 设置 Cookie(HttpOnly refresh_token)
    Vue->>Vue: 保存 access_token, token_expiry

    loop 每次调用API
        Vue->>Vue: 检查 token 是否即将过期
        alt token 有效
            Vue->>Go: GET /api/data (Bearer access_token)
            Go-->>Vue: 返回数据
        else token 过期
            Vue->>Go: POST /auth/refresh (携带 Cookie)
            Go->>Okta: 用 refresh_token 换新 access_token
            Okta-->>Go: 返回新 access_token + 新 refresh_token
            Go-->>Vue: 返回新的 access_token (Cookie 更新)
            Vue->>Vue: 更新 sessionStorage 中的 token
            Vue->>Go: 重试原请求 (Bearer new token)
            Go-->>Vue: 返回数据
        end
    end

✅ 关键点

项目 说明
Access Token 前端持有,用于调用 API(短期有效)
Refresh Token 后端保存在 HttpOnly Cookie(长期有效)
刷新触发 前端 axios 拦截器检测过期 → 调用 /auth/refresh
优点 安全(refresh_token 不暴露),兼容性强
缺点 前端逻辑稍复杂,需要 token 拦截器

🧠 方案二:后端自动刷新(BFF 模式)

这种架构下,前端不需要关心 access_token,所有请求都通过后端代理。

rust 复制代码
sequenceDiagram
    participant User as 👤 用户
    participant Vue as 🖥️ 前端(Vue)
    participant Go as 🧠 BFF服务(Golang)
    participant Okta as 🔐 Okta 授权服务器
    participant API as ☁️ 第三方受保护API

    User->>Vue: 登录请求
    Vue->>Go: POST /auth/login {username, password}
    Go->>Okta: 获取 access_token + refresh_token
    Okta-->>Go: 返回 tokens
    Go->>Go: 将 tokens 存入服务器 session / redis
    Go-->>Vue: 设置 session cookie (HttpOnly)

    loop 每次调用业务接口
        Vue->>Go: GET /api/data (自动带 session cookie)
        Go->>Go: 从 session 中取 access_token
        alt token 未过期
            Go->>API: Bearer access_token
            API-->>Go: 返回数据
        else token 过期
            Go->>Okta: 使用 refresh_token 换取新 access_token
            Okta-->>Go: 返回新 tokens
            Go->>Go: 更新 session
            Go->>API: 使用新 token 调用
            API-->>Go: 返回数据
        end
        Go-->>Vue: 返回数据
    end

✅ 关键点

项目 说明
Access Token 存在后端(前端完全看不到)
Refresh Token 存在后端(安全)
刷新触发 后端自动检测过期后刷新
优点 前端逻辑简单,XSS 风险极低
缺点 后端压力大(所有请求需代理),不适合纯前后端分离系统

⚖️ 两种方案对比总结

项目 前端触发刷新(分离式) 后端自动刷新(BFF)
前端是否保存 access_token ✅ 是 ❌ 否
Refresh Token 存放位置 HttpOnly Cookie 后端 Session / Redis
是否需要 axios 拦截器 ✅ 需要 ❌ 不需要
安全性 高(但依赖前端 CSP) 最高
可扩展性 强(适合 SPA / 多端) 一般(适合单体站点)
实现复杂度 中等 较高(需后端 session 管理)

🧩 推荐结论(针对你当前架构)

你目前是:

  • Vue 前端;
  • Golang 后端;
  • Okta 授权;
  • 前端调用后端 API(带 Authorization)。

👉 所以:

✅ 推荐使用 方案一:前端触发刷新

即保留 axios 拦截器,让后端仅负责 /auth/refresh 的实现。

这套方案:

  • 兼顾安全与简洁;
  • refresh_token 从不暴露给浏览器;
  • Access Token 自动刷新,无需用户频繁登录。
相关推荐
黄俊懿2 分钟前
【深入理解SpringCloud微服务】Spring-Security作用与原理解析
java·后端·安全·spring·spring cloud·微服务·架构师
我是谁的程序员3 分钟前
iOS 开发中证书创建与管理中的常见问题
后端
塔能物联运维10 分钟前
设备自适应采样率忽视能耗致续航降 后来结合功耗模型动态调优
java·后端·struts
我是谁的程序员11 分钟前
iPhone 耗电异常检测的思路,从系统电池统计、克魔(KeyMob)、Instruments等工具出发
后端
掘金一周16 分钟前
前端一行代码生成数千页PDF,dompdf.js新增分页功能| 掘金一周 12.25
前端·javascript·后端
ServBay17 分钟前
掌握这9个GO技巧,代码高效又高能
后端·go
rchmin18 分钟前
Spring Boot自动装配原理解析
java·spring boot·后端
程序员小假25 分钟前
我们来说一下 synchronized 与 ReentrantLock 的区别
java·后端
码事漫谈1 小时前
C++多线程中join与detach机制深度解析
后端
okseekw1 小时前
Java反射:解锁框架开发的终极密码,让代码拥有"动态灵魂"!
java·后端