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

Java實現JWT登錄認證的示例代碼

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

什么是JWT?

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

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

在這里插入圖片描述

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

Token驗證失敗的情況?

token過期

密鑰不正確

篡改了頭部、載荷等

為什么需要令牌?

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

如何實現?

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

添加依賴:

<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);

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

        return builder.compact();
    }

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

jwt配置:

application.yaml:

user:
  jwt:
    # 設置jwt簽名加密時使用的秘鑰
    user-secret-key: xxx
    # 設置jwt過期時間
    user-ttl: 7200000
    # 設置前端傳遞過來的令牌名稱
    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è)務需求獲?。?/p>

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

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

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

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

登錄業(yè)務邏輯:

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>

其他關聯代碼:

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

測試:

登錄接口:

在這里插入圖片描述

其他接口:

在這里插入圖片描述

在這里插入圖片描述

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

相關文章

  • java二維數組遍歷的2種代碼

    java二維數組遍歷的2種代碼

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

    Java實現單例模式的五種方式總結

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

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

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

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

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

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

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

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

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

    Java 正則表達式功能及應用

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

    Spring框架實現滑動驗證碼功能的代碼示例

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

    你肯定能看懂的Java IO相關知識總結

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

    java map遍歷的四種方法總結

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

最新評論

合肥市| 竹北市| 丰县| 固镇县| 赞皇县| 叶城县| 缙云县| 新密市| 囊谦县| 湾仔区| 广河县| 泾阳县| 大名县| 阳高县| 阳高县| 修武县| 长乐市| 徐州市| 凤庆县| 星子县| 杭州市| 铜川市| 甘孜县| 林甸县| 姜堰市| 苍南县| 三门峡市| 临泉县| 青龙| 抚松县| 赣榆县| 澎湖县| 赣州市| 商河县| 肃北| 玉田县| 罗定市| 甘泉县| 青海省| 金川县| 宜君县|