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

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

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

什么是JWT?

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

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

在這里插入圖片描述

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

Token驗證失敗的情況?

token過期

密鑰不正確

篡改了頭部、載荷等

為什么需要令牌?

  • 承載了一定的數(shù)據(jù)信息,減少數(shù)據(jù)庫訪問次數(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) {
        // 指定簽名的時候使用的簽名算法,也就是header那部分
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

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

        // 設(shè)置jwt的body
        JwtBuilder builder = Jwts.builder()
                // 如果有私有聲明,一定要先設(shè)置這個自己創(chuàng)建的私有的聲明,這個是給builder的claim賦值,一旦寫在標(biāo)準(zhǔn)的聲明賦值之后,就是覆蓋了那些標(biāo)準(zhǔn)的聲明的
                .setClaims(claims)
                // 設(shè)置簽名使用的簽名算法和簽名使用的秘鑰
                .signWith(signatureAlgorithm, secretKey.getBytes(StandardCharsets.UTF_8))
                // 設(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簽名加密時使用的秘鑰
    user-secret-key: xxx
    # 設(shè)置jwt過期時間
    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(存儲用戶登錄信息,方便其他業(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. 校驗用戶名和密碼
        UserLogin userLogin = userMapper.getUserByName(username);
        if (userLogin == null){
            throw new BaseException("用戶名或密碼錯誤");
        }
        password = DigestUtils.md5DigestAsHex(password.getBytes());
        if (!password.equals(userLogin.getPassword())){
            throw new BaseException("用戶名或密碼錯誤");
        }

        //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;
}

測試:

登錄接口:

在這里插入圖片描述

其他接口:

在這里插入圖片描述

在這里插入圖片描述

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

相關(guān)文章

  • java二維數(shù)組遍歷的2種代碼

    java二維數(shù)組遍歷的2種代碼

    這篇文章主要介紹了java二維數(shù)組遍歷的2種代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-07-07
  • Java實現(xiàn)單例模式的五種方式總結(jié)

    Java實現(xiàn)單例模式的五種方式總結(jié)

    這篇文章主要介紹了如何實現(xiàn)一個單例模式,包括構(gòu)造器私有化、提供靜態(tài)私有變量和公共獲取實例接口,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-01-01
  • 解決Mybatis映射文件mapper.xml中的注釋問題

    解決Mybatis映射文件mapper.xml中的注釋問題

    這篇文章主要介紹了解決Mybatis映射文件mapper.xml中的注釋問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教。
    2022-01-01
  • Java Collections.sort()排序代碼案例

    Java Collections.sort()排序代碼案例

    這篇文章主要介紹了Java Collections.sort()排序代碼案例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • Java開發(fā)必會的Linux命令

    Java開發(fā)必會的Linux命令

    這篇文章主要介紹了Java開發(fā)必會的Linux命令,幫助大家更好地進(jìn)行java開發(fā),感興趣的小伙伴們可以參考一下
    2015-12-12
  • springboot+dynamicDataSource動態(tài)添加切換數(shù)據(jù)源方式

    springboot+dynamicDataSource動態(tài)添加切換數(shù)據(jù)源方式

    這篇文章主要介紹了springboot+dynamicDataSource動態(tài)添加切換數(shù)據(jù)源方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • Java 正則表達(dá)式功能及應(yīng)用

    Java 正則表達(dá)式功能及應(yīng)用

    自從jdk1.4推出java.util.regex包,就為我們提供了很好的Java正則表達(dá)式應(yīng)用平臺,因為Java正則表達(dá)式是一個很龐雜的體系。
    2010-03-03
  • Spring框架實現(xiàn)滑動驗證碼功能的代碼示例

    Spring框架實現(xiàn)滑動驗證碼功能的代碼示例

    之前項目需要在驗證碼模塊,增加滑動驗證碼,用來給手機(jī)端使用的,大概看了下,主要方法就是將圖片切割,然后記住偏移量,進(jìn)行滑動,所以本文給大家介紹了Spring框架實現(xiàn)滑動驗證碼功能的方法示例,需要的朋友可以參考下
    2024-07-07
  • 你肯定能看懂的Java IO相關(guān)知識總結(jié)

    你肯定能看懂的Java IO相關(guān)知識總結(jié)

    群里有大佬說想讓我寫一篇NIO,一直也沒寫,但是和同事聊天也說對Java的IO不是很清晰,因此今天就寫下Java的io,先打個基礎(chǔ),下次寫NIO,需要的朋友可以參考下
    2021-05-05
  • java map遍歷的四種方法總結(jié)

    java map遍歷的四種方法總結(jié)

    以下是我整理的關(guān)于java中map的遍歷的四種方法。需要的朋友可以過來參考下,希望對大家有所幫助
    2013-10-10

最新評論

新野县| 惠来县| 连城县| 汤原县| 安吉县| 海宁市| 蓬莱市| 诸暨市| 开鲁县| 石林| 吉林市| 五大连池市| 普定县| 北海市| 安阳县| 怀宁县| 桐柏县| 垣曲县| 沐川县| 金坛市| 海南省| 仙桃市| 科尔| 舞阳县| 伊宁市| 讷河市| 通江县| 页游| 湖口县| 乐山市| 岐山县| 海宁市| 罗源县| 桑植县| 彰武县| 瑞安市| 梁山县| 定边县| 依安县| 满洲里市| 灵寿县|