笔者写文章的时候,都会把图片通过自己搭建的一个简单站点 https://imgbed.sugarat.top/ 把图片上传到各种云的对象存储服务(OSS)上。

然后通过CDN访问,保证图片有可靠的访问速度和质量。

本着尽可能简单,减少对后端依赖的原则,上传令牌是在本地(Node.js)生成并设置一个过期时间,在浏览器中直接粘贴,存放在 LocalStorage 中,过期就在本地重新生成一次就行。

但现在生成的时候也还有2个麻烦点:① 依赖 Node.js 环境 ② 关键的秘钥存储在本地文件中

本次迭代就是把这2个麻烦点解决掉!

生成原理

又拍云

参考文档:token 认证生成

简化成 JS 代码如下

// 基本配置
const operator = '账号'
const password = '密码'
const method = 'PUT' // 上传时用到的请求方法
const urlPrefix = 'bucketName/sourcePrefix' // 资源在OSS上的桶名称和公共路径前缀
const expire = Math.floor(Date.now() / 1000) + 3600 // 过期时间 1小时后过期 // 计算token
const token = base64(hmacSha1(MD5(password), `${method}&${urlPrefix}&${expire}`)) // 最终上传用到的请求头
const Authorization = `UPYUN ${operator}:${token}`

依赖的算法

  • base64:将数据转换为 ASCII 字符串的编码
  • HMAC_SHA-1:基于 SHA-1 哈希算法的消息认证码,用于验证消息的完整性和真实性
  • MD5:哈希函数,用于生成数据的数字指纹

七牛云

参考文档:上传凭证URL安全的Base64编码

简化成 JS 代码如下

// 基本配置
const accessKey = 'ACCESS_KEY'
const secretKey = 'SECRET_KEY'
const bucket = 'BUCKET_NAME' // OSS 桶名称
const expires = Math.floor(Date.now() / 1000) + 3600 // 过期时间 1小时后过期 const encodedFlags = base64ToUrlSafe(base64(JSON.stringify({
scope: bucket,
deadline: expires,
})))
const encodedSign = base64ToUrlSafe(base64(hmacSha1(secretKey, encodedFlags))) // 最终上传用到的令牌
const uploadToken = `${accessKey}:${encodedSign}:${encodedFlags}`

其中 base64ToUrlSafe 是 “URL安全的Base64编码” 相关的方法

URL安全的Base64编码适用于以URL方式传递Base64编码结果的场景。该编码方式的基本过程是先将内容以Base64格式编码为字符串,然后检查该结果字符串,将字符串中的加号+换成中划线-,并且将斜杠/换成下划线_

// 实现如下
function base64ToUrlSafe(v: string) {
return v.replace(/\//g, '_').replace(/\+/g, '-')
}

其它依赖算法和又拍云基本一致 hmacSha1base64

加密方法的实现

这里分别介绍浏览器和 Node.js 环境下的简单实现。

前端浏览器侧实现

base64 和 HMAC_SHA-1 算法都有现成的实现,分别可以使用浏览器提供的 btoaCrypto API。

function base64(value: string) {
return btoa(value)
}

HMAC_SHA-1

在阅读 MDN: Crypto API 文档时先可以看到 Crypto.subtle 的描述。

从字面意思不难看出就是我们需要的API。

HMAC 的例子中,就可以找到我们需要的关键信息:

关键代码如下

const encoder = new TextEncoder()
const encoded = encoder.encode(value)
const signature = await window.crypto.subtle.sign('HMAC', key, encoded)

其中 key 是我们需要的密钥,可以用 SubtleCrypto.importKey() 导入生成。

const encoder = new TextEncoder()
const key = await window.crypto.subtle.importKey(
'raw',
encoder.encode(password), // password 是我们的密钥
{ name: 'HMAC', hash: { name: 'SHA-1' } },
false,
['sign'],
)

最终我们的方法实现如下。

async function hmacSha1(key: string, value: string) {
const encoder = new TextEncoder() const cryptoKey = await window.crypto.subtle.importKey(
'raw',
encoder.encode(key),
{ name: 'HMAC', hash: { name: 'SHA-1' } },
false,
['sign'],
) const data = encoder.encode(value)
const hashBuffer = await window.crypto.subtle.sign('HMAC', cryptoKey, data) return arrayBufferToBase64(hashBuffer) // 返回 base64 格式的结果
} function arrayBufferToBase64(buffer: ArrayBuffer) {
const uint8Array = new Uint8Array(buffer)
const base64String = String.fromCharCode(...uint8Array)
return btoa(base64String)
}

MD5

MD5 可以使用 开源库 spark-md5

import SparkMD5 from 'spark-md5'

export function MD5(str: string): string {
return SparkMD5.hash(str)
}

Node.js 实现

Node.js 环境下,可以直接使用内置 node:crypto 模块提供的各种加密算法,十分方便。

HMAC_SHA-1

import crypto from 'crypto'

function hmacSha1(key: string, value: string) {
const hmac = crypto.createHmac('sha1', key)
hmac.update(value) // 设置用于计算校验值的字符串
return hmac.digest('base64') // 计算校验值,并按照 base64 返回
}

MD5

import crypto from 'crypto'

function MD5(value: string) {
const md5 = crypto.createHash('md5')
md5.update(value) // 设置用于计算 MD5 值的字符串
return md5.digest('hex') // 计算 MD5 值,并直接以十六进制字符串返回
}

安全问题

针对存储 账号&密码 等敏感信息的可以使用浏览器提供的账号密码管理能力存储。

例如 Chrome 中提供的 PasswordCredential 相关API。

调用后就可以唤起存储的弹窗。

最后

总结一下:浏览器中也可以使用window.crypto提供的 API,完成常用的加密算法调用,同时也可以在 Web Worker 中使用,可以有效提升性能。

当前这一版图床,应该也还不是最终版,后续计划将部分管理功能以某种可能得形式完成纯静态的支持。

欢迎评论区交流想法&意见

浏览器中生成 OSS 令牌 | Web Crypto API的更多相关文章

  1. 内卷时代下的前端技术-使用JavaScript在浏览器中生成PDF文档

    背景 在计量领域中,计量检定是一种重要形式,主要用于评定计量器具的计量性能,确定其量值是否准确一致,实现手段包括计量检验.出具检定证书和加封盖印等. 在检定证书这一环节,存在一个难点,就是无法在线预览 ...

  2. 关于点击ztree的节点将页面生成到easyui的新增选项卡(easyui-tabs)时,总是在浏览器中生成一个新的页面的问题

    最近的项目中用到了easyui,还有ztree菜单.在这里将我遇到的一些问题写出来算是做个笔记吧. 这是我头一次在博客园里分享代码,我的处女作,写的不好的地方还望各位见谅! 由于很久没有写过前台的东西 ...

  3. python中生成JWK(json web token)

    #需要安装pyjwt import jwt import time # 使用 sanic 作为restful api 框架 def create_token(request): grant_type ...

  4. VS2010中生成遇到的 web.config 问题

    1. 错误:无法在此路径使用此配置节.当站点管理员使用继承的配置文件中的  <location allowOverride="false">  锁定对此节的访问时会出现 ...

  5. Web Animations API (JS动画利器)

    原文地址:→传送门 写在前面 之前学习了CSS animation/setTimeout/setInterval/requestAnimationFrame等,这些都可以用在某种场景下的小动画,也可以 ...

  6. Web Storage API的介绍和使用

    目录 简介 浏览器的本地存储技术 Web Storage相关接口 浏览器兼容性 隐身模式 使用Web Storage API 总结 简介 Web Storage为浏览器提供了方便的key value存 ...

  7. ASP.NET Core Web API中带有刷新令牌的JWT身份验证流程

    ASP.NET Core Web API中带有刷新令牌的JWT身份验证流程 翻译自:地址 在今年年初,我整理了有关将JWT身份验证与ASP.NET Core Web API和Angular一起使用的详 ...

  8. 第十一章:WEB浏览器中的javascript

    客户端javascript涵盖在本系列的第二部分第10章,主要讲解javascript是如何在web浏览器中实现的,这些章节介绍了大量的脚本宿主对象,这些对象可以表示浏览器窗口.文档树的内容.这些章节 ...

  9. JavaScript权威指南--WEB浏览器中的javascript

    知识要点 1.客户端javascript window对象是所有客户端javascript特性和API的主要接入点.它表示web浏览器的一个窗口或窗体,并且可以用window表示来引用它.window ...

  10. HTML5 Web Speech API 结合Ext实现浏览器语音识别以及输入

    简介      Web Speech API是HTML5技术中的一个提供原生语音识别技术的API,Google Chrome在25版之后开始支持Web Speech API,Google也提供了一个 ...

随机推荐

  1. 信奥生(OIER)请看,包囊初赛复赛全真模拟赛!

    luogu 动态追踪! 唠唠嗑 感谢 tyw 代理团主对比赛的贡献,但是由于我和 tyw 的关系紧张,tyw 取消了我和她的一切合作.CTFPC-3rd 的出题.宣传工作都交到了我手上,我这次亚历山大 ...

  2. 【Vue】分组类型排名查询功能

    一.书接上回: https://www.cnblogs.com/mindzone/p/17749725.html 这个效果被否决了,产品要求一定要UI的来,UI效果如图: 按人为主体的时候,固定有4个 ...

  3. 【转载】 PID原理与参数调试

    原文地址: http://m.elecfans.com/article/1153309.html --------------------------------------------------- ...

  4. 一个域名可以对应多个IP吗,一个IP可以对应多个域名吗?

    本文谈两个问题:一个域名可以对应多个IP吗,一个IP可以对应多个域名吗? 问题1:一个IP可以对应多个域名吗? 因为域名都是由各个域名供应商提供的,我们可以在不同的域名供应商那里买不同的域名,然后把这 ...

  5. bazel编译报错:absl/base/policy_checks.h:79:2: error: #error "C++ versions less than C++14 are not supported."

    使用bazel编译一个软件时报错,报错的信息为: absl/base/policy_checks.h:79:2: error: #error "C++ versions less than ...

  6. 备忘 : 使用VS2022后,发现C盘空间越来越少怎么办?

    背景 自从安装完VS2022后,感觉C盘容量肉眼可见的降低.之前2019并没有产生如此严重的情况.后面查看发现,Designer/Cache缓存的数据很大(截图是已经删除过的) 解决方案 在平台的反馈 ...

  7. 用户案例 | 蜀海供应链基于 Apache DolphinScheduler 的数据表血缘探索与跨大版本升级经验

    导读 蜀海供应链是集销售.研发.采购.生产.品保.仓储.运输.信息.金融为一体的餐饮供应链服务企业.2021年初,蜀海信息技术中心大数据技术研发团队开始测试用DolphinScheduler作为数据中 ...

  8. 实操教程 | 触发器实现 Apache DolphinScheduler 失败钉钉自动告警

    作者 | sqlboy-yuzhenc 背景介绍 在实际应用中,我们经常需要将特定的任务通知给特定的人,虽然 Apache DolphinScheduler 在安全中心提供了告警组和告警实例,但是配置 ...

  9. 2023 CCPC 桂林题解

    gym H. Sweet Sugar 一个经典贪心是从下到上,如果子树 \(u\) 剩下的部分(一定包含 \(u\))包含合法连通块,那么这个连通块给答案贡献 \(1\),切断 \(u\) 与 \(f ...

  10. celery僵死导致jumpserver提示 连接WebSocket失败

    celery僵死导致jumpserver提示连接WebSocket失败 Celery的任务监控位于堡垒机 "作业中心"下的"任务监控" 中,点击打开新的页面如下 ...