实现一个带有授权码和使用时间限制的Spring Boot项目

news2025/5/26 3:45:16
  1. 生成和验证授权码
  2. 记录授权时间和过期时间
  3. 实现授权逻辑

以下是具体的实现方法:

1. 生成和验证授权码

可以使用加密技术生成和验证授权码。授权码中可以包含有效期等信息,并使用密钥进行签名。

示例代码:

java复制代码
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.util.Date;
import java.util.concurrent.TimeUnit;

public class LicenseManager {

    private static final String SECRET_KEY = "your_secret_key";

    public static String generateLicense(String userId, long durationInDays) throws Exception {
        long currentTime = System.currentTimeMillis();
        long expiryTime = currentTime + TimeUnit.DAYS.toMillis(durationInDays);
        String data = userId + ":" + expiryTime;
        Mac sha256HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKey = new SecretKeySpec(SECRET_KEY.getBytes(), "HmacSHA256");
        sha256HMAC.init(secretKey);
        String hash = Base64.getEncoder().encodeToString(sha256HMAC.doFinal(data.getBytes()));
        return Base64.getEncoder().encodeToString((data + ":" + hash).getBytes());
    }

    public static boolean validateLicense(String license) throws Exception {
        String decodedLicense = new String(Base64.getDecoder().decode(license));
        String[] parts = decodedLicense.split(":");
        if (parts.length != 3) return false;

        String data = parts[0] + ":" + parts[1];
        String hash = parts[2];

        Mac sha256HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKey = new SecretKeySpec(SECRET_KEY.getBytes(), "HmacSHA256");
        sha256HMAC.init(secretKey);
        String calculatedHash = Base64.getEncoder().encodeToString(sha256HMAC.doFinal(data.getBytes()));

        if (!calculatedHash.equals(hash)) return false;

        long expiryTime = Long.parseLong(parts[1]);
        return System.currentTimeMillis() <= expiryTime;
    }
}

2. 记录授权时间和过期时间

通过授权码生成和验证,可以记录和检查授权时间和过期时间。

3. 实现授权逻辑

在Spring Boot应用中,通过拦截器或过滤器来验证每次请求的授权码。

示例代码:

创建一个拦截器

java复制代码
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class LicenseInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String license = request.getHeader("License-Key");
        if (license == null || !LicenseManager.validateLicense(license)) {
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "License is invalid or expired");
            return false;
        }
        return true;
    }
}

注册拦截器

在Spring Boot配置类中注册拦截器:

java复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private LicenseInterceptor licenseInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(licenseInterceptor).addPathPatterns("/**");
    }
}

4. 使用授权码

公司使用项目时,需要将授权码放在HTTP请求头中:

http复制代码
GET /your/api/endpoint
License-Key: generated_license_key

5. 重新授权

在3个月到期后,需要重新生成并分发新的授权码。可以为此创建一个管理端点来帮助重新授权。

示例代码:

java复制代码
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class LicenseController {

    @GetMapping("/generateLicense")
    public String generateLicense(@RequestParam String userId, @RequestParam long durationInDays) throws Exception {
        return LicenseManager.generateLicense(userId, durationInDays);
    }
} 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2385810.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SGlang 推理模型优化(PD架构分离)

一、技术背景 随着大型语言模型&#xff08;LLM&#xff09;广泛应用于搜索、内容生成、AI助手等领域&#xff0c;对模型推理服务的并发能力、响应延迟和资源利用效率提出了前所未有的高要求。与模型训练相比&#xff0c;推理是一个持续进行、资源消耗巨大的任务&#xff0c;尤…

Vue语法【2】

1.插值表达式&#xff1a; 语法规则&#xff1a; {{Vue实例中data的变量名}}使用场景&#xff1a; 插值表达式一般使用在文本内容中&#xff0c;如果是元素的属性内容中则无法使用&#xff1b; 案例&#xff1a; <!DOCTYPE html> <html lang"en"> &l…

2.2.1 05年T2

引言 本文将从一预习、二自习、三学习、四复习等四个阶段来分析2005年考研英语阅读第二篇文章。为了便于后续阅读&#xff0c;我将第四部分复习放在了首位。 四、复习 方法&#xff1a;错误思路分析总结考点文章梳理 4.1 错题分析 题目&#xff1a;26&#xff08;细节题&…

Linux虚拟文件系统(2)

2.3 目录项-dentry 目录项&#xff0c;即 dentry&#xff0c;用来记录文件的名字、索引节点指针以及与其他目录项的关联关系。多个关联的目录项&#xff0c;就构成了文件系统的目录结构。和上一章中超级块和索引节点不同&#xff0c;目录项并不是实际存在于磁盘上的&#xff0c…

【数据结构】栈和队列(上)

目录 一、栈&#xff08;先进后出、后进先出的线性表&#xff09; 1、栈的概念及结构 2、栈的底层结构分析 二、代码实现 1、定义一个栈 2、栈的初始化 3、入栈 3、增容 4、出栈 5、取栈顶 6、销毁栈 一、栈&#xff08;先进后出、后进先出的线性表&#xff09; 1、…

科技赋能·长效治理|无忧树建筑修缮渗漏水长效治理交流会圆满举行!

聚焦行业痛点&#xff0c;共话长效未来&#xff01;5月16日&#xff0c;由无忧树主办的主题为“科技赋能长效治理”的建筑修缮渗漏水长效治理技术交流会在上海圆满举行。来自全国的建筑企业代表、专家学者、技术精英齐聚一堂&#xff0c;共探渗漏治理前沿技术&#xff0c;见证科…

【闲聊篇】java好丰富!

1、在学习mybatis-plus的文档时&#xff0c;发现引入了solon依赖&#xff0c;才发现这是一个对标spring生态的框架&#xff0c;有意思&#xff01; 还有若依框架&#xff0c;真的好丰富~~~~~~~ 2、今天面试官问我&#xff0c;他说很少遇到用redission做延迟队列的。后面我就反…

6.3.2图的深度优先遍历

知识总览&#xff1a; 树的先根遍历&#xff1a; 采用递归一直找某个节点的子树直到找不到从上往下找 访问根节点1&#xff0c;1的子树有2、3、4,访问2&#xff0c;2节点子树有5访问5,5没有子树&#xff0c;退回到2,2还有子树6访问6,6没有子树再退回到2,2的子树都被访问了再退…

畅游Diffusion数字人(30):情绪化数字人视频生成

畅游Diffusion数字人(0):专栏文章导航 前言:仅从音频生成此类运动极具挑战性,因为它在音频和运动之间存在一对多的相关性。运动视频的情绪是多元化的选择,之前的工作很少考虑情绪化的数字人生成。今天解读一个最新的工作FLOAT,可以生成制定情绪化的数字人视频。 目录 贡献…

UE5 Va Res发送请求、处理请求、json使用

文章目录 介绍发送一个Get请求发送Post请求设置请求头请求体带添json发送请求完整的发送蓝图 处理收到的数据常用的json处理节点 介绍 UE5 自带的Http插件&#xff0c;插件内自带json解析功能 发送一个Get请求 只能写在事件图表里 发送Post请求 只能写在事件图表里 设置…

【读代码】BAGEL:统一多模态理解与生成的模型

一、项目概览 1.1 核心定位 BAGEL是字节跳动推出的开源多模态基础模型,具有70亿激活参数(140亿总参数)。该模型在统一架构下实现了三大核心能力: 多模态理解:在MME、MMBench等9大评测基准中超越Qwen2.5-VL等主流模型文本生成图像:生成质量媲美SD3等专业生成模型智能图像…

隧道自动化监测解决方案

行业现状 隧道作为一种重要的交通运输通道&#xff0c;不管是缓解交通压力&#xff0c;还是让路网结构更趋于完善&#xff0c;它都有着不可估量的作用。隧道在运营过程中&#xff0c;由于受到材料退化、地震、人为因素等影响会发生隧道主体结构的损坏和劣化。若不及时检修和维护…

游戏引擎学习第307天:排序组可视化

简短谈谈直播编程的一些好处。 上次结束后&#xff0c;很多人都指出代码中存在一个拼写错误&#xff0c;因此这次我们一开始就知道有一个 bug 等待修复&#xff0c;省去了调试寻找错误的时间。 今天的任务就是修复这个已知 bug&#xff0c;然后继续排查其他潜在的问题。如果短…

java接口自动化初识

简介 了解什么是接口和为什么要做接口测试。并且知道接口自动化测试应该学习哪些技术以及接口自动化测试的落地过程。 一、什么是接口 在这里我举了一个比较生活化的例子&#xff0c;比如我们有一台笔记本&#xff0c;在笔记本的两端有很多插口。例如&#xff1a;USB插口。那…

NVM安装使用及问题解决

目录 一、前言 二、NVM安装 三、配置下载源 四、nvm使用 五、安装nvm list available没有的版本 六、问题解决 一、前言 如果你开发 Node.js 项目&#xff0c;可能会遇到这些问题&#xff1a; ①新项目需要 Node.js 18&#xff0c;但老项目只能用 Node.js 14&#xff0c;…

C++学习之STL学习:string类使用

在之前的学习中&#xff0c;我们初步了解到了STL的概念&#xff0c;接下来我们将深入学习STL中的string类的使用&#xff0c;后续还会结合他们的功能进行模拟实验 目录 为什么要学习string类&#xff1f; 标准库中的string类 string类&#xff08;了解&#xff09; auto和范围…

5月24日day35打卡

模型可视化与推理 知识点回顾&#xff1a; 三种不同的模型可视化方法&#xff1a;推荐torchinfo打印summary权重分布可视化进度条功能&#xff1a;手动和自动写法&#xff0c;让打印结果更加美观推理的写法&#xff1a;评估模式 作业&#xff1a;调整模型定义时的超参数&#x…

Linux(7)——进程(概念篇)

目录 一、基本概念 二、描述进程——PCB 1.task_struct——PCB的一种 2.task_struct的内容分类 三、查看进程 1.通过系统目录查看 2.通过ps命令查看 四、通过系统调用获取进程的PID和PPID 五、通过系统调用创建进程 1.fork函数创建子进程 2.使用if来引出问题 六、L…

前端流行框架Vue3教程:24.动态组件

24.动态组件 有些场景会需要在两个组件间来回切换&#xff0c;比如 Tab 界面 我们准备好A B两个组件ComponentA ComponentA App.vue代码如下&#xff1a; <script> import ComponentA from "./components/ComponentA.vue" import ComponentB from "./…

Unity3D仿星露谷物语开发48之显示树桩效果

1、目标 砍完橡树之后会露出树桩&#xff0c;然后树桩可以用斧头收割&#xff0c;并将创建一个新的砍树桩的粒子效果。 这里有&#xff1a;一种作物收获后创造另一种作物的逻辑。 2、分析 在SO_CropDetailsList中&#xff0c;Harvested Transform Item Code可以指定收获后生…