欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

如何使用Spring Boot實(shí)現(xiàn)接口時(shí)間戳鑒權(quán)

 更新時(shí)間:2025年06月09日 10:01:41   作者:weixin_43833540  
這篇文章主要為大家詳細(xì)介紹了如何使用Spring Boot實(shí)現(xiàn)接口時(shí)間戳鑒權(quán),文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴要了解下

Spring Boot實(shí)現(xiàn)接口時(shí)間戳鑒權(quán),簽名(sign)和時(shí)間戳(ts)放入請(qǐng)求頭(Header)。

一、請(qǐng)求頭參數(shù)設(shè)計(jì)

參數(shù)名類(lèi)型說(shuō)明
tsLong13位時(shí)間戳(Unix毫秒值),必填,標(biāo)識(shí)請(qǐng)求有效期
signString簽名值,必填,用于校驗(yàn)請(qǐng)求合法性

二、簽名算法調(diào)整(Header版)

1. 構(gòu)造原始字符串

str = key + url_encode(path) + ts

path:請(qǐng)求的URL路徑部分(不含查詢(xún)參數(shù)和域名),例如:/api/v1/user。

url_encode(path):需對(duì)路徑中的特殊字符進(jìn)行URL編碼(如中文、/等無(wú)需編碼,但空格需轉(zhuǎn)義為%20)。

2. 生成簽名 SIGN

sgin = md5(S).toLowerCase()

結(jié)果轉(zhuǎn)換為小寫(xiě)字符串,與請(qǐng)求頭中的sign對(duì)比校驗(yàn)。

三、Spring Boot實(shí)現(xiàn)流程

1. 創(chuàng)建攔截器(Interceptor)

用于攔截請(qǐng)求,校驗(yàn)ts和sign的合法性。

import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Objects;

public class AuthInterceptor implements HandlerInterceptor {
    private final String secretKey; // 從配置文件獲取密鑰,例如application.properties
    private final long maxClockSkew = 60 * 1000; // 時(shí)間窗口:60秒(允許客戶(hù)端與服務(wù)端的時(shí)間誤差)

    public AuthInterceptor(String secretKey) {
        this.secretKey = secretKey;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 1. 校驗(yàn)時(shí)間戳是否存在
        String ts = request.getHeader("ts");
        if (StringUtils.isEmpty(ts)) {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            response.setContentType("application/json");
            // 返回錯(cuò)誤信息:缺少時(shí)間戳
            return false;
        }

        // 2. 校驗(yàn)時(shí)間戳格式及有效性
        long ts;
        try {
            ts = Long.parseLong(ts );
        } catch (NumberFormatException e) {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            // 返回錯(cuò)誤信息:時(shí)間戳格式錯(cuò)誤
            return false;
        }
        long currentTime = System.currentTimeMillis();
        if (currentTime - ts > maxClockSkew|| ts - currentTime > maxClockSkew) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            // 返回錯(cuò)誤信息:請(qǐng)求已過(guò)期
            return false;
        }

        // 3. 校驗(yàn)簽名是否存在
        String sign= request.getHeader("sign");
        if (StringUtils.isEmpty(sign)) {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            // 返回錯(cuò)誤信息:缺少簽名
            return false;
        }

        // 4. 構(gòu)造原始簽名字符串并生成簽名
        String path = request.getRequestURI(); // 獲取路徑,例如"/api/v1/user"
        String encodedPath = URLEncoder.encode(path, StandardCharsets.UTF_8.toString())
                .replace("+", "%20") // 處理空格編碼差異(URLEncoder默認(rèn)用+,此處統(tǒng)一為%20)
                .replace("%7E", "~"); // 保留波浪線~的原始格式
        String rawString = secretKey + encodedPath + tsHeader;

        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] digest = md.digest(rawString.getBytes(StandardCharsets.UTF_8));
            StringBuilder sb = new StringBuilder();
            for (byte b : digest) {
                sb.append(String.format("%02x", b)); // 轉(zhuǎn)換為小寫(xiě)16進(jìn)制字符串
            }
            String generatedSign = sb.toString();

            // 5. 對(duì)比簽名
            if (!generatedSign.equals(sign)) {
                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                // 返回錯(cuò)誤信息:簽名校驗(yàn)失敗
                return false;
            }
        } catch (Exception e) {
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            return false;
        }

        return true; // 校驗(yàn)通過(guò),允許請(qǐng)求繼續(xù)
    }
}

2. 配置攔截器(WebMvcConfigurer)

將攔截器注冊(cè)到Spring Boot的攔截器鏈中,指定需要鑒權(quán)的接口路徑。

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 {
    private final String secretKey; // 從配置文件獲取密鑰,例如通過(guò)@Value注入

    public WebConfig(String secretKey) {
        this.secretKey = secretKey;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        AuthInterceptor authInterceptor = new AuthInterceptor(secretKey);
        registry.addInterceptor(authInterceptor)
                .addPathPatterns("/api/v1/**") // 需要鑒權(quán)的接口路徑(如/api/v1下所有接口)
                .excludePathPatterns("/api/v1/public/**"); // 無(wú)需鑒權(quán)的公共接口(可選)
    }
}

3. 配置文件(application.properties)

# 密鑰(建議從環(huán)境變量或配置中心獲取,而非硬編碼)
auth.secret-key=your_secret_key_here

四、客戶(hù)端請(qǐng)求示例(以Postman為例)

1. 請(qǐng)求頭參數(shù)

名稱(chēng)
ts1686048000000(當(dāng)前時(shí)間戳,13位Long)
sign計(jì)算得到的簽名值(如e10adc3949ba59abbe56e057f20f883e)

2. 簽名計(jì)算步驟(JavaScript示例)

function generateSignature(key, path, ts) {
    const encodedPath = encodeURIComponent(path).replace(/[!'()*]/g, encodeURIComponent); // 嚴(yán)格編碼特殊字符
    const rawString = key + encodedPath + ts;
    const md5 = require('crypto-js/md5'); // 需要安裝crypto-js庫(kù)
    return md5(rawString).toString().toLowerCase();
}

// 示例調(diào)用
const key = 'your_secret_key';
const path = '/api/v1/user'; // 接口路徑
const ts = Date.now(); // 當(dāng)前時(shí)間戳(13位)
const sign = generateSignature(key, path, ts);
console.log(sign); // 輸出簽名值

到此這篇關(guān)于如何使用Spring Boot實(shí)現(xiàn)接口時(shí)間戳鑒權(quán)的文章就介紹到這了,更多相關(guān)Spring Boot接口時(shí)間戳鑒權(quán)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Kotlin常用函數(shù)let,with,run,apply用法與區(qū)別案例詳解

    Kotlin常用函數(shù)let,with,run,apply用法與區(qū)別案例詳解

    這篇文章主要介紹了Kotlin常用函數(shù)let,with,run,apply用法與區(qū)別案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • IDEA 程序包不存在,找不到符號(hào)但是明明存在對(duì)應(yīng)的jar包(問(wèn)題分析及解決方案)

    IDEA 程序包不存在,找不到符號(hào)但是明明存在對(duì)應(yīng)的jar包(問(wèn)題分析及解決方案)

    這篇文章主要介紹了IDEA 程序包不存在,找不到符號(hào)但是明明存在對(duì)應(yīng)的jar包 的解決方案,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Redis之SpringDataRedis用法詳解

    Redis之SpringDataRedis用法詳解

    這篇文章主要介紹了Redis之SpringDataRedis的用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • Spring Boot整合Elasticsearch實(shí)現(xiàn)全文搜索引擎案例解析

    Spring Boot整合Elasticsearch實(shí)現(xiàn)全文搜索引擎案例解析

    ElasticSearch作為基于Lucene的搜索服務(wù)器,既可以作為一個(gè)獨(dú)立的服務(wù)部署,也可以簽入Web應(yīng)用中。SpringBoot作為Spring家族的全新框架,使得使用SpringBoot開(kāi)發(fā)Spring應(yīng)用變得非常簡(jiǎn)單,在本案例中我們給大家介紹Spring Boot整合Elasticsearch實(shí)現(xiàn)全文搜索引擎
    2017-11-11
  • Java實(shí)現(xiàn)提取Word文檔表格數(shù)據(jù)

    Java實(shí)現(xiàn)提取Word文檔表格數(shù)據(jù)

    使用Java實(shí)現(xiàn)Word文檔表格數(shù)據(jù)的提取,可以確保數(shù)據(jù)處理的一致性和準(zhǔn)確性,同時(shí)大大減少所需的時(shí)間和成本,下面我們來(lái)看看具體實(shí)現(xiàn)方法吧
    2025-01-01
  • 解讀查看zookeeper事務(wù)日志的正確姿勢(shì)

    解讀查看zookeeper事務(wù)日志的正確姿勢(shì)

    這篇文章主要介紹了解讀查看zookeeper事務(wù)日志的正確姿勢(shì)。具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • hibernate和mybatis對(duì)比分析

    hibernate和mybatis對(duì)比分析

    通過(guò)本文給分享了hibernate和mybatis對(duì)比分析,從開(kāi)發(fā)對(duì)比,系統(tǒng)調(diào)優(yōu)對(duì)比,對(duì)象管理與抓取策略,緩存機(jī)制對(duì)比等方面給大家詳細(xì)介紹,需要的朋友參考下吧
    2017-09-09
  • 詳解自動(dòng)注冊(cè)Gateway網(wǎng)關(guān)路由配置

    詳解自動(dòng)注冊(cè)Gateway網(wǎng)關(guān)路由配置

    這篇文章主要為大家介紹了自動(dòng)注冊(cè)Gateway網(wǎng)關(guān)路由配置的方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • SpringBoot集成Redis流程詳解

    SpringBoot集成Redis流程詳解

    這篇文章主要介紹了SpringBoot集成Redis流程詳解,導(dǎo)入jar包,編寫(xiě)配置類(lèi),編寫(xiě)util類(lèi),配置yml這四個(gè)步驟,有詳細(xì)的代碼示例,,需要的朋友可以參考下
    2023-05-05
  • Spring學(xué)習(xí)筆記之RedisTemplate的配置與使用教程

    Spring學(xué)習(xí)筆記之RedisTemplate的配置與使用教程

    這篇文章主要給大家介紹了關(guān)于Spring學(xué)習(xí)筆記之RedisTemplate配置與使用的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用spring具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-06-06

最新評(píng)論