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

Java實(shí)現(xiàn)JWT登錄認(rèn)證的示例代碼

 更新時(shí)間:2025年04月03日 10:43:34   作者:TimberWill  
Java中我們可以使用諸如JJWT這樣的庫來生成和驗(yàn)證JWT,本文主要介紹了Java實(shí)現(xiàn)JWT登錄認(rèn)證的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

什么是JWT?

JWT(Json Web Token),簡(jiǎn)單來說就是:web領(lǐng)域中基于json格式的令牌。是最常用的令牌規(guī)范。

  • 第一部分:Header(頭),指定了令牌的簽名算法、令牌類型。
  • 第二部分:Payload(有效載荷),使用Base64來編碼的,不是加密算法,能夠解碼。因此,該部分不適合存放用戶的私密信息(如:密碼)。
  • 第三部分:Signature(簽名),將第一部分和第二部分通過密鑰加密得到。

在這里插入圖片描述

解析Token可以根據(jù)第三部分解密得到前兩部分的信息,再比對(duì)前端傳來的用戶信息,完成校驗(yàn)。

Token驗(yàn)證失敗的情況?

token過期

密鑰不正確

篡改了頭部、載荷等

為什么需要令牌?

  • 承載了一定的數(shù)據(jù)信息,減少數(shù)據(jù)庫訪問次數(shù)
  • 具有一定的防偽功能

如何實(shí)現(xiàn)?

該部分代碼不需要硬記,理解后直接使用即可。

添加依賴:

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

JwtUtils.java(生成、解析Token的工具類)

public class JwtUtil {

    /**
     * 生成Token
     * @param secretKey
     * @param ttlMillis
     * @param claims
     * @return
     */
    public static String createToken(String secretKey, long ttlMillis, Map<String, Object> claims) {
        // 指定簽名的時(shí)候使用的簽名算法,也就是header那部分
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        // 生成token的過期時(shí)間
        long expMillis = System.currentTimeMillis() + ttlMillis;
        Date exp = new Date(expMillis);

        // 設(shè)置jwt的body
        JwtBuilder builder = Jwts.builder()
                // 如果有私有聲明,一定要先設(shè)置這個(gè)自己創(chuàng)建的私有的聲明,這個(gè)是給builder的claim賦值,一旦寫在標(biāo)準(zhǔn)的聲明賦值之后,就是覆蓋了那些標(biāo)準(zhǔn)的聲明的
                .setClaims(claims)
                // 設(shè)置簽名使用的簽名算法和簽名使用的秘鑰
                .signWith(signatureAlgorithm, secretKey.getBytes(StandardCharsets.UTF_8))
                // 設(shè)置過期時(shí)間
                .setExpiration(exp);

        return builder.compact();
    }

    /**
     * 解析token
     * @param secretKey
     * @param token
     * @return
     */
    public static Claims parseToken(String secretKey, String token) {
        // 得到DefaultJwtParser
        Claims claims = Jwts.parser()
                // 設(shè)置簽名的秘鑰
                .setSigningKey(secretKey.getBytes(StandardCharsets.UTF_8))
                // 設(shè)置需要解析的jwt
                .parseClaimsJws(token).getBody();
        return claims;
    }
 }

jwt配置:

application.yaml:

user:
  jwt:
    # 設(shè)置jwt簽名加密時(shí)使用的秘鑰
    user-secret-key: xxx
    # 設(shè)置jwt過期時(shí)間
    user-ttl: 7200000
    # 設(shè)置前端傳遞過來的令牌名稱
    user-token-name: token

JwtProperties:

@Component
@ConfigurationProperties(prefix = "user.jwt")
@Data
public class JwtProperties {

    private String userSecretKey;
    private long userTtl;
    private String userTokenName;
}

JwtClaimsConstant(管理常量):

public class JwtClaimsConstant {
    public static final String USER_ID = "userId";
}

jwt攔截器:

@Component
@Slf4j
public class JwtInterceptor implements HandlerInterceptor {

    @Resource
    private JwtProperties jwtProperties;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //1. 獲取用戶信息
        String token = request.getHeader(jwtProperties.getUserTokenName());
        //2. 判斷用戶信息是否有效,存入ThreadLocal
        try {
            Claims claims = JwtUtil.parseToken(jwtProperties.getUserSecretKey(), token);
            String userInfo = claims.get(JwtClaimsConstant.USER_ID).toString();

            if (StrUtil.isNotBlank(userInfo)){
                UserContext.setUser(Long.valueOf(userInfo));
            }

            //3. 放行
            return true;
        }catch (Exception e){
            //4. 不通過
            response.setStatus(401);
            return false;
        }

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //清除用戶信息
        UserContext.removeUser();
    }
}

WebMvc配置(添加jwt攔截器)

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Resource
    private JwtInterceptor jwtInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(jwtInterceptor)
                .addPathPatterns("/user/**")
                .excludePathPatterns("/user/user/login");
    }
}

UserContext(存儲(chǔ)用戶登錄信息,方便其他業(yè)務(wù)需求獲取)

public class UserContext {
    private static final ThreadLocal<Long> threadLocal = new ThreadLocal<>();

    /**
     * 獲取用戶信息
     * @return
     */
    public static Long getUser() {
        return threadLocal.get();
    }

    /**
     * 設(shè)置用戶信息
     * @param userId
     */
    public static void setUser(Long userId){
        threadLocal.set(userId);
    }

    /**
     * 移除用戶信息
     */
    public static void removeUser(){
        threadLocal.remove();
    }
}

登錄業(yè)務(wù)邏輯:

controller層:

@RestController
@RequestMapping("/user/user")
@Slf4j
public class UserController {

    @Resource
    private UserService userService;

    @PostMapping("/login")
    public UserLoginVO login(@RequestBody UserLoginDTO userLoginDTO){
        log.info("用戶登錄:{}",userLoginDTO);
        return userService.login(userLoginDTO);
    }
}

service層:

public interface UserService {
    UserLoginVO login(UserLoginDTO userLoginDTO);
}
@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private JwtProperties jwtProperties;

    @Override
    public UserLoginVO login(UserLoginDTO userLoginDTO) {
        String username = userLoginDTO.getUsername();
        String password = userLoginDTO.getPassword();
        //1. 校驗(yàn)用戶名和密碼
        UserLogin userLogin = userMapper.getUserByName(username);
        if (userLogin == null){
            throw new BaseException("用戶名或密碼錯(cuò)誤");
        }
        password = DigestUtils.md5DigestAsHex(password.getBytes());
        if (!password.equals(userLogin.getPassword())){
            throw new BaseException("用戶名或密碼錯(cuò)誤");
        }

        //2. 生成token
        HashMap<String, Object> claims = new HashMap<>();
        claims.put(JwtClaimsConstant.USER_ID, userLogin.getId());
        String token = JwtUtil.createToken(
                jwtProperties.getUserSecretKey(),
                jwtProperties.getUserTtl(),
                claims);

        //3. 封裝vo
        UserLoginVO loginVO = UserLoginVO.builder()
                .token(token)
                .userId(userLogin.getId())
                .username(userLogin.getUsername())
                .build();

        return loginVO;
    }
}

mapper層:

@Mapper
public interface UserMapper {
    UserLogin getUserByName(String username);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.sky.user.mapper.UserMapper">

    <select id="getUserByName" resultType="com.sky.user.pojo.entity.UserLogin">
        select *
        from user_login where username = #{username} and is_delete = 0;
    </select>
</mapper>

其他關(guān)聯(lián)代碼:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserLoginDTO {
    /**
     * 用戶名
     */
    private String username;

    /**
     * 密碼
     */
    private String password;

}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserLoginVO {
    private String token;
    private Long userId;
    private String username;
}

測(cè)試:

登錄接口:

在這里插入圖片描述

其他接口:

在這里插入圖片描述

在這里插入圖片描述

到此這篇關(guān)于Java實(shí)現(xiàn)JWT登錄認(rèn)證的示例代碼的文章就介紹到這了,更多相關(guān)Java JWT登錄認(rèn)證內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • Spring 定時(shí)任務(wù)@Scheduled 注解四大參數(shù)用法解析

    Spring 定時(shí)任務(wù)@Scheduled 注解四大參數(shù)用法解析

    本文詳細(xì)介紹了Spring框架中使用@Scheduled注解實(shí)現(xiàn)定時(shí)任務(wù)的方法,重點(diǎn)講解了fixedRate、fixedDelay、cron和initialDelay這四個(gè)參數(shù)的用法,并通過實(shí)例代碼進(jìn)行了詳細(xì)說明,感興趣的朋友一起看看吧
    2025-01-01
  • Java+ElasticSearch+Pytorch實(shí)現(xiàn)以圖搜圖功能

    Java+ElasticSearch+Pytorch實(shí)現(xiàn)以圖搜圖功能

    這篇文章主要為大家詳細(xì)介紹了Java如何利用ElasticSearch和Pytorch實(shí)現(xiàn)以圖搜圖功能,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解一下
    2023-06-06
  • SpringBoot單點(diǎn)登錄實(shí)現(xiàn)過程詳細(xì)分析

    SpringBoot單點(diǎn)登錄實(shí)現(xiàn)過程詳細(xì)分析

    這篇文章主要介紹了SpringBoot單點(diǎn)登錄實(shí)現(xiàn)過程,單點(diǎn)登錄英文全稱Single?Sign?On,簡(jiǎn)稱就是SSO。它的解釋是:在多個(gè)應(yīng)用系統(tǒng)中,只需要登錄一次,就可以訪問其他相互信任的應(yīng)用系統(tǒng)
    2022-12-12
  • 詳解在Spring Boot中使用Mysql和JPA

    詳解在Spring Boot中使用Mysql和JPA

    本文向你展示如何在Spring Boot的Web應(yīng)用中使用Mysq數(shù)據(jù)庫,也充分展示Spring Boot的優(yōu)勢(shì)
    2017-04-04
  • Java中線程狀態(tài)+線程安全問題+synchronized的用法詳解

    Java中線程狀態(tài)+線程安全問題+synchronized的用法詳解

    這篇文章主要介紹了Java中線程狀態(tài)+線程安全問題+synchronized的用法詳解,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • 新手初學(xué)Java List 接口

    新手初學(xué)Java List 接口

    這篇文章主要介紹了Java集合操作之List接口及其實(shí)現(xiàn)方法,詳細(xì)分析了Java集合操作中List接口原理、功能、用法及操作注意事項(xiàng),需要的朋友可以參考下
    2021-07-07
  • 詳解Spring中@Valid和@Validated注解用法

    詳解Spring中@Valid和@Validated注解用法

    本文將以新增一個(gè)員工為功能切入點(diǎn),以常規(guī)寫法為背景,慢慢烘托出?@Valid?和?@Validated?注解用法詳解,文中的示例代碼講解詳細(xì),感興趣的可以了解一下
    2022-07-07
  • SpringBoot配置Clickhouse的示例代碼

    SpringBoot配置Clickhouse的示例代碼

    這篇文章主要介紹了SpringBoot配置Clickhouse的示例代碼,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考價(jià)值,需要的朋友可以參考下
    2022-02-02
  • SpringBoot集成elasticsearch使用圖文詳解

    SpringBoot集成elasticsearch使用圖文詳解

    Spring Boot集成Elasticsearch其實(shí)非常簡(jiǎn)單,這篇文章主要給大家介紹了關(guān)于SpringBoot集成elasticsearch使用的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-04-04
  • springboot+mybatis攔截器方法實(shí)現(xiàn)水平分表操作

    springboot+mybatis攔截器方法實(shí)現(xiàn)水平分表操作

    這篇文章主要介紹了springboot+mybatis攔截器方法實(shí)現(xiàn)水平分表操作,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下
    2022-08-08

最新評(píng)論