最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Java?token主流框架之JWT

 更新時(shí)間:2023年05月26日 08:27:35   作者:蜀山劍客李沐白  
JWT(JSON?Web?Token)是一種基于JSON格式的輕量級(jí)的、用于身份認(rèn)證的開(kāi)放標(biāo)準(zhǔn),它通過(guò)在用戶(hù)和服務(wù)器之間傳遞一個(gè)安全的、可靠的、獨(dú)立的JSON對(duì)象來(lái)進(jìn)行身份驗(yàn)證和授權(quán),本文將詳細(xì)給大家介紹Java?token主流框架之JWT,需要的朋友可以參考下

1. JWT的概念和特點(diǎn)

JWT是一種輕量級(jí)、可擴(kuò)展、可自包含的身份驗(yàn)證和授權(quán)機(jī)制。它是由三個(gè)部分組成:頭部(Header)、載荷(Payload)和簽名(Signature)。它的目的是為了在網(wǎng)絡(luò)應(yīng)用間傳遞聲明信息,以便在某些情況下對(duì)用戶(hù)進(jìn)行身份驗(yàn)證和授權(quán)。

JWT有以下幾個(gè)特點(diǎn):

  • 簡(jiǎn)潔(Compact):JWT是一個(gè)緊湊且自包含的數(shù)據(jù)格式,它可以通過(guò)HTTP頭或URL參數(shù)進(jìn)行傳輸。
  • 自包含(Self-contained):JWT包含了足夠的信息,使得客戶(hù)端可以判斷是否信任該令牌,而不需要查詢(xún)服務(wù)器。
  • 可擴(kuò)展(Extensible):由于JWT是基于JSON格式的,因此可以自定義Payload中的屬性來(lái)適應(yīng)各種業(yè)務(wù)需求。
  • 安全(Secure):JWT使用簽名來(lái)驗(yàn)證發(fā)送方和接收方之間的身份。當(dāng)使用加密算法時(shí),還可以確保消息的機(jī)密性。

2. JWT的三個(gè)部分:Header、Payload和Signature

JWT由三個(gè)部分組成:頭部、載荷和簽名。

Header

JWT頭部是一個(gè)JSON對(duì)象,它描述了生成和處理該JWT所需要的算法和類(lèi)型信息。例如:

{
  "alg": "HS256",
  "typ": "JWT"
}

其中,"alg"表示簽名算法,"typ"表示令牌類(lèi)型。

Payload

JWT載荷是一個(gè)JSON對(duì)象,它包含了有關(guān)令牌和聲明的信息。例如:

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

其中,"sub"表示主題(Subject),"name"表示名稱(chēng),"iat"表示令牌的發(fā)行時(shí)間(Issued At)。

除了這些聲明外,JWT還支持自定義聲明。例如:

{
  "iss": "http://example.com",
  "exp": 1516239922,
  "custom_key": "custom_value"
}

其中,"iss"表示頒發(fā)者(Issuer),"exp"表示到期時(shí)間(Expiration Time),"custom_key"是自定義聲明。

Signature

JWT簽名用于驗(yàn)證消息的發(fā)送方和消息的完整性。簽名由頭部、載荷和密鑰組成,并使用指定的算法進(jìn)行計(jì)算。例如,使用HS256算法可以使用以下方法生成簽名:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

其中,"."是分隔符,"secret"是密鑰。

3. JWT的工作過(guò)程

JWT的工作流程可以描述為以下三個(gè)步驟:

  • 用戶(hù)通過(guò)用戶(hù)名和密碼進(jìn)行身份驗(yàn)證。
  • 服務(wù)器對(duì)用戶(hù)進(jìn)行身份驗(yàn)證,并創(chuàng)建一個(gè)JWT令牌,并將其返回給客戶(hù)端。
  • 客戶(hù)端在以后的請(qǐng)求中使用該令牌進(jìn)行身份驗(yàn)證,并在需要訪問(wèn)API時(shí)將其發(fā)送到服務(wù)器。

具體的工作過(guò)程如下:

  • 當(dāng)用戶(hù)成功登錄到Web應(yīng)用程序時(shí),服務(wù)器將根據(jù)用戶(hù)提供的憑據(jù)(例如用戶(hù)名和密碼)驗(yàn)證用戶(hù)的身份,并創(chuàng)建一個(gè)JWT令牌。
  • 服務(wù)器將從Payload中提取一些信息(例如用戶(hù)ID或名稱(chēng))并將其加密到JWT令牌中。
  • JWT令牌將被加密,并在響應(yīng)頭或URL參數(shù)中返回給客戶(hù)端。
  • 在以后的請(qǐng)求中,客戶(hù)端將JWT令牌作為授權(quán)標(biāo)頭或URL參數(shù)發(fā)送給服務(wù)器。
  • 服務(wù)器將使用該令牌進(jìn)行身份驗(yàn)證,并檢查令牌是否被篡改或過(guò)期。如果令牌有效,則允許訪問(wèn)所需的API。

4. JWT常見(jiàn)的應(yīng)用場(chǎng)景和優(yōu)勢(shì)

JWT主要應(yīng)用于Web應(yīng)用程序和RESTful API,以下是它的一些常見(jiàn)應(yīng)用場(chǎng)景:

  • 身份驗(yàn)證(Authentication):JWT可以作為身份驗(yàn)證機(jī)制,代替?zhèn)鹘y(tǒng)的Cookie和Session方式。
  • 前后端分離(Front and Backend Separation):在前后端分離的架構(gòu)中,JWT可以在前端和后端之間進(jìn)行信任關(guān)系的建立和維護(hù)。
  • 單點(diǎn)登錄(Single Sign On):在多個(gè)Web應(yīng)用程序中共享JWT,可以實(shí)現(xiàn)單點(diǎn)登錄的效果。
  • 信息交換(Information Exchange):JWT可以用于安全地在不同的系統(tǒng)之間傳遞信息。

JWT的優(yōu)勢(shì)包括:

  • 無(wú)狀態(tài)(Stateless): JWT不需要在服務(wù)器上保存用戶(hù)狀態(tài)和會(huì)話(huà)信息,從而簡(jiǎn)化了服務(wù)器的負(fù)載和擴(kuò)展性。
  • 可擴(kuò)展(Extensible):JWT的載荷可以包含自定義聲明,從而滿(mǎn)足各種業(yè)務(wù)場(chǎng)景的需求。
  • 安全(Secure):JWT使用簽名來(lái)驗(yàn)證發(fā)送方和接收方之間的身份。當(dāng)使用加密算法時(shí),還可以確保消息的機(jī)密性。
  • 支持跨域(Cross-origin):JWT可以通過(guò)HTTP頭或URL參數(shù)進(jìn)行傳輸,因此支持跨域訪問(wèn)。

5. 如何避免JWT的安全風(fēng)險(xiǎn)

使用JWT時(shí),需要注意以下幾點(diǎn)來(lái)避免安全風(fēng)險(xiǎn):

  • 不要將敏感信息存儲(chǔ)在JWT中:JWT可以被解密,因此不應(yīng)該將任何敏感信息存儲(chǔ)在JWT中。
  • 對(duì)于重要的操作,需要再次進(jìn)行身份驗(yàn)證:JWT只是一種身份驗(yàn)證機(jī)制,而不是授權(quán)機(jī)制。即使用戶(hù)已經(jīng)通過(guò)JWT進(jìn)行了身份驗(yàn)證,服務(wù)器仍然需要對(duì)他們進(jìn)行授權(quán)和驗(yàn)證。
  • 使用HTTPS協(xié)議:由于JWT可能被篡改,因此需要確保使用HTTPS協(xié)議以確保消息的機(jī)密性和完整性。
  • 設(shè)置合理的過(guò)期時(shí)間:如果JWT永遠(yuǎn)不會(huì)過(guò)期,那么它就會(huì)成為一個(gè)長(zhǎng)期有效的訪問(wèn)令牌,從而增加了訪問(wèn)令牌被攻擊者盜用的風(fēng)險(xiǎn)。

6.代碼案例

  • JJWT(Java JWT)

JJWT 是一個(gè)流行的 Java JWT 庫(kù),它提供了一種創(chuàng)建、編碼和解碼 JWT 的簡(jiǎn)便方法。以下是一個(gè)基于 JJWT 的示例:

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
public class JwtUtils {
    private static final long EXPIRATION_TIME = 864_000_000; // 10 days
    private static final String SECRET_KEY = "secretKey";
    public static String generateToken(String username) {
        Date expiryDate = new Date(System.currentTimeMillis() + EXPIRATION_TIME);
        return Jwts.builder()
                .setSubject(username)
                .setExpiration(expiryDate)
                .signWith(SignatureAlgorithm.HS512, SECRET_KEY)
                .compact();
    }
    public static String getUsernameFromToken(String token) {
        Claims claims = Jwts.parser()
                .setSigningKey(SECRET_KEY)
                .parseClaimsJws(token)
                .getBody();
        return claims.getSubject();
    }
    public static boolean isTokenValid(String token) {
        try {
            Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}

在這個(gè)示例中,JwtUtils 類(lèi)包含了生成令牌、從令牌中獲取用戶(hù)名和驗(yàn)證令牌的三個(gè)方法。注意,在實(shí)際使用中,SECRET_KEY 應(yīng)該更加復(fù)雜。

  • Spring Security

Spring Security 是一個(gè)流行的安全框架,它提供了一種輕松的方式來(lái)保護(hù)應(yīng)用程序和 APIs。Spring Security 支持使用 JWT 進(jìn)行身份驗(yàn)證和授權(quán)。以下是一個(gè)基于 Spring Security 的示例:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserService userService;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeRequests()
                .antMatchers("/api/auth/**").permitAll()
                .anyRequest().authenticated()
                .and()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    }
    @Bean
    public JwtAuthenticationFilter jwtAuthenticationFilter() {
        return new JwtAuthenticationFilter();
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
    }
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

在這個(gè)示例中,SecurityConfig 類(lèi)擴(kuò)展了 WebSecurityConfigurerAdapter 類(lèi),并覆蓋了其中的 configure(HttpSecurity http) 方法。在這個(gè)方法中,Spring Security 配置了哪些 URL 公開(kāi),哪些需要進(jìn)行身份驗(yàn)證,并且禁用了 CSRF 保護(hù)。配置完后,Spring Security 將 JWT 過(guò)濾器添加到 UsernamePasswordAuthenticationFilter 前面。

在實(shí)現(xiàn)身份驗(yàn)證之前,需要?jiǎng)?chuàng)建一個(gè)用戶(hù)服務(wù)類(lèi)并實(shí)現(xiàn) UserDetailsService 接口。以下是一個(gè)示例:

@Service
public class UserService implements UserDetailsService {
    @Autowired
    private UserRepository userRepository;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username)
                .orElseThrow(() -> new UsernameNotFoundException("User not found"));
        return new org.springframework.security.core.userdetails.User(user.getUsername(),
                user.getPassword(), new ArrayList<>());
    }
}

在這個(gè)示例中,UserService 類(lèi)實(shí)現(xiàn)了 UserDetailsService 接口,并覆蓋其中的 loadUserByUsername(String username) 方法。該方法根據(jù)給定的用戶(hù)名查找用戶(hù),如果用戶(hù)不存在,則拋出 UsernameNotFoundException 異常。

最后,需要實(shí)現(xiàn)一個(gè) JWT 過(guò)濾器來(lái)驗(yàn)證 JWT 并將身份驗(yàn)證信息加載到 Spring Security 的上下文中。以下是一個(gè)基于 Spring Security 的 JWT 過(guò)濾器示例:

public class JwtAuthenticationFilter extends OncePerRequestFilter {
    private static final String AUTHORIZATION_HEADER = "Authorization";
    private static final String TOKEN_PREFIX = "Bearer ";
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        try {
            String token = parseToken(request);
            if (token != null && JwtUtils.isTokenValid(token)) {
                String username = JwtUtils.getUsernameFromToken(token);
                UserDetails userDetails = userService.loadUserByUsername(username);
                UsernamePasswordAuthenticationToken authenticationToken =
                        new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            }
        } catch (Exception e) {
            logger.error("Error while processing authentication request", e);
        }
        filterChain.doFilter(request, response);
    }
    private String parseToken(HttpServletRequest request) {
        String header = request.getHeader(AUTHORIZATION_HEADER);
        if (header != null && header.startsWith(TOKEN_PREFIX)) {
            return header.substring(TOKEN_PREFIX.length());
        }
        return null;
    }
}

在這個(gè)示例中,JWT 過(guò)濾器實(shí)現(xiàn)了 OncePerRequestFilter 類(lèi),并覆蓋了其中的 doFilterInternal 方法。在該方法中,它從請(qǐng)求頭中獲取 JWT,驗(yàn)證 JWT,將身份驗(yàn)證信息加載到 Spring Security 的上下文中,然后放行請(qǐng)求。

  • Apache Shiro

Apache Shiro 是一個(gè)功能豐富的安全框架,可以用于保護(hù) Java 應(yīng)用程序和 APIs。Shiro 支持使用 JWT 進(jìn)行身份驗(yàn)證和授權(quán)。以下是一個(gè)基于 Shiro 的示例:

@Configuration
public class ShiroConfig {
    @Bean
    public DefaultWebSecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(realm());
        return securityManager;
    }
    @Bean
    public JwtRealm realm() {
        JwtRealm realm = new JwtRealm();
        realm.setCredentialsMatcher(jwtCredentialsMatcher());
        return realm;
    }
    @Bean
    public JwtCredentialsMatcher jwtCredentialsMatcher() {
        return new JwtCredentialsMatcher();
    }
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();
        filterFactoryBean.setSecurityManager(securityManager);
        filterFactoryBean.setFilters(filters());
        filterFactoryBean.setFilterChainDefinitionMap(filterChainDefinition());
        return filterFactoryBean;
    }
    private Map<String, String> filterChainDefinition() {
        Map<String, String> filterChainDefinition = new LinkedHashMap<>();
        filterChainDefinition.put("/api/auth/**", "anon");
        filterChainDefinition.put("/**", "jwt");
        return filterChainDefinition;
    }
    private Map<String, Filter> filters() {
        Map<String, Filter> filters = new HashMap<>();
        filters.put("jwt", new JwtFilter());
        return filters;
    }
}

在這個(gè)示例中,Shiro 配置了一個(gè)名為 securityManager 的安全管理器,其中包含一個(gè)名為 realm 的域。realm 類(lèi)需要實(shí)現(xiàn) org.apache.shiro.realm.Realm 接口,并覆蓋其中的 supports(AuthenticationToken token)getAuthenticationInfo(AuthenticationToken token) 方法來(lái)驗(yàn)證 JWT。

類(lèi)似于 Spring Security,需要實(shí)現(xiàn)一個(gè) JWT 過(guò)濾器來(lái)驗(yàn)證 JWT 并將身份驗(yàn)證信息加載到 Shiro 的上下文中。以下是一個(gè)基于 Shiro 的 JWT 過(guò)濾器示例:

public class JwtFilter extends AuthenticatingFilter {
    @Override
    protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
        String token = getToken(request);
        if (StringUtils.isNotBlank(token) && JwtUtils.isTokenValid(token)) {
            return new JwtToken(token);
        }
        return null;
    }
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        httpServletResponse.setStatus(HttpStatus.UNAUTHORIZED.value());
        return false;
    }
    private String getToken(ServletRequest request) {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        String token = httpServletRequest.getHeader("Authorization");
        if (StringUtils.isNotBlank(token) && token.startsWith("Bearer ")) {
            return token.substring(7);
        } else {
            return null;
        }
    }
}

在這個(gè)示例中,JWT 過(guò)濾器擴(kuò)展了 AuthenticatingFilter 類(lèi),并覆蓋了其中的 createToken(ServletRequest request, ServletResponse response)onAccessDenied(ServletRequest request, ServletResponse response) 方法。createToken 方法創(chuàng)建一個(gè) JwtToken 對(duì)象,并將 JWT 設(shè)置為憑據(jù)。onAccessDenied 方法在未找到 JWT 時(shí)返回 UNAUTHORIZED 狀態(tài)碼。

以上就是詳解Java token主流框架之JWT的詳細(xì)內(nèi)容,更多關(guān)于Java token框架JWT的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 分享Java開(kāi)發(fā)必須掌握的日志分析命令

    分享Java開(kāi)發(fā)必須掌握的日志分析命令

    這篇文章主要介紹了分享Java開(kāi)發(fā)必須掌握的日志分析命令,在日常工作中,如果我們遇到線上問(wèn)題,一般的處理步驟應(yīng)該是先保留現(xiàn)場(chǎng),然后再考慮回滾,之后再是解決問(wèn)題
    2019-07-07
  • 淺談Java中Properties類(lèi)的詳細(xì)使用

    淺談Java中Properties類(lèi)的詳細(xì)使用

    properties類(lèi)繼承自hashtable,通常和io流結(jié)合使用。它最突出的特點(diǎn)是將key/value作為配置屬性寫(xiě)入到配置文件中以實(shí)現(xiàn)配置持久化,或從配置文件中讀取這些屬性。它的這些配置文件的規(guī)范后綴名為".properties"。表示了一個(gè)持久的屬性集
    2021-06-06
  • Jenkin郵件收發(fā)實(shí)現(xiàn)原理及過(guò)程詳解

    Jenkin郵件收發(fā)實(shí)現(xiàn)原理及過(guò)程詳解

    這篇文章主要介紹了Jenkin郵件收發(fā)實(shí)現(xiàn)原理及過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • 淺談JVM內(nèi)存溢出的幾種方式與解決方法

    淺談JVM內(nèi)存溢出的幾種方式與解決方法

    內(nèi)存溢出分為兩大類(lèi):OutOfMemoryError和StackOverflowError,以下舉出10個(gè)內(nèi)存溢出的情況,并通過(guò)實(shí)例代碼的方式講解了是如何出現(xiàn)內(nèi)存溢出的,感興趣的可以了解一下
    2024-01-01
  • 淺談java面向?qū)ο蟮臄?shù)組化信息處理

    淺談java面向?qū)ο蟮臄?shù)組化信息處理

    下面小編就為大家?guī)?lái)一篇淺談java面向?qū)ο蟮臄?shù)組化信息處理。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-06-06
  • Spring?Boot?lombok在高版本idea中注解不生效的解決辦法

    Spring?Boot?lombok在高版本idea中注解不生效的解決辦法

    這篇文章主要介紹了Spring?Boot?lombok在高版本idea中注解不生效的解決辦法,文中介紹了三種解決方案,分別是使用ptg插件生成方法、添加Lombok依賴(lài)或指定1.18.30版本并清除構(gòu)建配置,需要的朋友可以參考下
    2025-05-05
  • RestTemplate在Spring或非Spring環(huán)境下使用精講

    RestTemplate在Spring或非Spring環(huán)境下使用精講

    這篇文章主要為大家介紹了RestTemplate在Spring或非Spring環(huán)境下使用精講,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-03-03
  • Java?Swing實(shí)現(xiàn)掃雷源碼

    Java?Swing實(shí)現(xiàn)掃雷源碼

    這篇文章主要為大家詳細(xì)介紹了Java?Swing實(shí)現(xiàn)掃雷源碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • SpringBoot 自動(dòng)配置原理及源碼解析

    SpringBoot 自動(dòng)配置原理及源碼解析

    SpringBoot 在項(xiàng)目啟動(dòng)的時(shí)候封裝了創(chuàng)建對(duì)象的方法,無(wú)需我們手動(dòng)配置,接下來(lái)通過(guò)本文給大家介紹SpringBoot 自動(dòng)配置原理解析及源碼展示,感興趣的朋友一起看看吧
    2021-06-06
  • spring WebSocket示例詳解

    spring WebSocket示例詳解

    websocket是Html5新增加特性之一,目的是瀏覽器與服務(wù)端建立全雙工的通信方式,本篇文章主要介紹了spring WebSocket示例詳解 ,有興趣的可以了解一下。
    2017-01-01

最新評(píng)論

巩留县| 罗平县| 保山市| 舞钢市| 永泰县| 龙江县| 福鼎市| 兰西县| 岢岚县| 南溪县| 平度市| 太和县| 五大连池市| 渝中区| 铁岭县| 广灵县| 万山特区| 定日县| 五家渠市| 新兴县| 吴忠市| 兴国县| 南召县| 建瓯市| 康平县| 长岛县| 临夏市| 朝阳区| 伊金霍洛旗| 安远县| 日喀则市| 嘉定区| 耿马| 屏山县| 图木舒克市| 潜江市| 西宁市| 乌恰县| 新蔡县| 乌海市| 星子县|