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

實(shí)戰(zhàn)SpringBoot集成JWT實(shí)現(xiàn)token驗(yàn)證

 更新時(shí)間:2021年12月31日 17:21:43   作者:炒燜煎糖板栗  
本文詳細(xì)講解了SpringBoot集成JWT實(shí)現(xiàn)token驗(yàn)證,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

JWT可以理解為一個(gè)加密的字符串,里面由三部分組成:頭部(Header)、負(fù)載(Payload)、簽名(signature)

由base64加密后的header和payload使用.連接組成的字符串,然后通過header中聲明的加密方式進(jìn)行加鹽secret組合加密,然后就構(gòu)成了JWT字符串

往期介紹了JWT相關(guān)概念以及基本操作,接下來介紹如何在SpringBoot中整合JWT實(shí)現(xiàn)登陸注冊(cè)

環(huán)境搭建

1、新建一個(gè)SpringBoot項(xiàng)目Jwt-Demo,引入項(xiàng)目后面需要用到的jar包

  <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--引入mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.3</version>
        </dependency>
        <!--引入mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.25</version>
        </dependency>
        <!--引入druid數(shù)據(jù)庫(kù)連接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.1</version>
        </dependency>
        <!--引入lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter-test</artifactId>
            <version>2.1.3</version>
        </dependency>
        <!--引入jwt-->
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.4.0</version>
        </dependency>
    </dependencies>

2、數(shù)據(jù)庫(kù)結(jié)構(gòu)

有一個(gè)JWT庫(kù),里面還有一個(gè)User表

3、配置文件application.properties

server.port=8989

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/JWT?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true
spring.datasource.username=root
spring.datasource.password=12345678

#mybatis掃描的包
mybatis.type-aliases-package=com.ylc
#mapper文件路徑
mybatis.mapper-locations=classpath:/**/*.xml

#開啟sql打印日志  logging.level后面是mybatis對(duì)應(yīng)的方法接口所在的包
logging.level.com.ylc.jwtdemo.dao=debug

4、Entity包下新建一個(gè)User類

import lombok.Data;

@Data
public class User {
    private  String username;
    private  String password;
    private  int id;
}

5、Dao包下新建一個(gè)UserDao

@Mapper
public interface UserDao {

    User login(User user);
}

6、Service包下新建一個(gè)USerService

public interface UserService {
    User login(User user);//登錄接口
}

7、UseService的實(shí)現(xiàn)類UserServiceImp

import java.util.HashMap;
import java.util.Map;

@Service
public class UserServiceImpI implements UserService {

    @Autowired
    private UserDao userDao;

    @Override
    public User login(User user) {
        User userdb=userDao.login(user);
        if(userdb!=null)
        {
            Map<String,String> map=new HashMap<>();
            map.put("name",userdb.getUsername());
            return userdb;
        }
        throw  new RuntimeException("登錄失敗");
    }
}

8、controller包下新建一個(gè)UserController

@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/user/login")
    public Map<String,Object> login(User user)
    {
        log.info("用戶名:"+user.getUsername());
        log.info("密碼:"+user.getPassword());
        Map<String,Object> map=new HashMap<>();
        try {
            userService.login(user);
            map.put("msg","登錄成功");
            map.put("code","200");
        }
        catch (Exception ex)
        {
            map.put("msg","登錄失敗");
        }

        return map;
    }
}

9、在resource文件夾下新建一個(gè)Usermapper文件

<?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">
<!--namespace 指的是要配置的全限定類名-->
<mapper namespace="com.ylc.jwtdemo.dao.UserDao">
    <select id="login" parameterType="com.ylc.jwtdemo.entity.User" resultType="com.ylc.jwtdemo.entity.User">
        select *from user where username=#{username} and password=#{password}
    </select>
</mapper>

10、JWT工具類JwtUtils

/**
 * JWT工具類
 * @author yanglingcong
 * @date 2021/12/31 11:24 AM
 */
public class JwtUtils {
    //鑒權(quán) 相當(dāng)于私鑰保存在服務(wù)器上
    private  static  final String  secret="##@$%@#S#WS";


    /**
     * 生成token
     * @author yanglingcong
     * @date 2021/12/31 11:23 AM
     * @param map
     * @return String
     */
    public static  String getToken(Map<String,String> map)
    {
        Calendar instance=Calendar.getInstance();
        //默認(rèn)七天過期
        instance.add(Calendar.DATE,7);
        //創(chuàng)建JWT
        JWTCreator.Builder builder = JWT.create();

        //payload
        map.forEach((k,v)->{
            builder.withClaim(k,v);
        });
        //指定令牌過期時(shí)間
        builder.withExpiresAt(instance.getTime());

        String token=builder.sign(Algorithm.HMAC256(secret));
        return token;
    }

    /**
     * 驗(yàn)證token
     * @author yanglingcong
     * @date 2021/12/31 11:26 AM
     * @param token
     */
    public  static  DecodedJWT  verify(String token) {
        return  JWT.require(Algorithm.HMAC256(secret)).build().verify(token);
    }

}

整個(gè)項(xiàng)目概覽

測(cè)試驗(yàn)證是否能夠連通數(shù)據(jù)庫(kù)

訪問:localhost:8989/user/login?username=ylc&password=123456

引入JWT

@Slf4j
@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/user/login")
    public Map<String,Object> login(User user)
    {
        log.info("用戶名:"+user.getUsername());
        log.info("密碼:"+user.getPassword());
        Map<String,Object> map=new HashMap<>();
        try {
            userService.login(user);
            map.put("msg","登錄成功");
            map.put("code","200");

            Map<String,String> payload=new HashMap<>();
            payload.put("name",user.getUsername());
            String token= JwtUtils.getToken(payload);
            map.put("token",token);
        }
        catch (Exception ex)
        {
            map.put("msg","登錄失敗");
        }

        return map;
    }

    @PostMapping("/test/verity")
    public  Map<String,String> verityToken(String token)
    {
        Map<String, String> map=new HashMap<>();
        log.info("token為"+token);
        try {
            DecodedJWT verify = JwtUtils.verify(token);
            map.put("msg","驗(yàn)證成功");
            map.put("state","true");
        }
        catch (Exception exception)
        {
            map.put("msg","驗(yàn)證失敗");
            exception.printStackTrace();
        }
        return map;
    }
}

登錄操作

訪問:http://localhost:8989/user/login?username=ylc&password=123456

驗(yàn)證操作

訪問:http://localhost:8989/test/verity

但是我們這樣寫在實(shí)際項(xiàng)目中是不合理的,把token生成的代碼放在了Controller中,業(yè)務(wù)邏輯是不能放在Controller層中的。假如很多接口都需要token來進(jìn)行驗(yàn)證保護(hù),那每一個(gè)接口都需要添加這樣一段代碼,造成代碼冗余。

程序優(yōu)化

如果是web項(xiàng)目使用攔截器進(jìn)行優(yōu)化,如果是springcloud項(xiàng)目在網(wǎng)關(guān)層進(jìn)行攔截,下面演示如何使用攔截器攔截

最好還把JWT生成token放在http請(qǐng)求頭,這樣就不需要把token當(dāng)成參數(shù)傳遞了

新建一個(gè)攔截器JwtInterceptor

/**
 * JWT攔截器
 * @author yanglingcong
 * @date 2021/12/31 12:39 PM
 */
public class JwtInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HashMap<String, String> map=new HashMap<>();
        //從http請(qǐng)求頭獲取token
        String token = request.getHeader("token");
        try {
            //如果驗(yàn)證成功放行請(qǐng)求
            DecodedJWT verify = JwtUtils.verify(token);
            return true;
        }
        catch (Exception exception)
        {
            map.put("msg","驗(yàn)證失?。?+exception);
        }
        String json = new ObjectMapper().writeValueAsString(map);
        response.setContentType("application/json:charset=UTF=8");
        response.getWriter().println(json);
        return false;
    }
}

然后把攔截器注冊(cè)到過濾器中,新建一個(gè)過濾器InterceptConfig

/**
 * @author yanglingcong
 */
@Configuration
public class InterceptConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //添加攔截器
        registry.addInterceptor(new JwtInterceptor())
                //攔截的路徑 需要進(jìn)行token驗(yàn)證的路徑
                .addPathPatterns("/test/verity")
                //放行的路徑
                .excludePathPatterns("/user/login");
    }
}

登錄是不需要攔截的,其他請(qǐng)求如果有需要驗(yàn)證token就放入攔截器的路徑

測(cè)試驗(yàn)證

在http請(qǐng)求頭中放入token,會(huì)被攔截器攔截驗(yàn)證token的有效性

總結(jié)

這就是SpringBoot整合JWT實(shí)際項(xiàng)目一個(gè)大概的流程,但是細(xì)節(jié)方面secret(私鑰)肯定每個(gè)用戶都是不一樣的,這里給寫死了,而且私鑰得保存在一個(gè)安全的地方。包括payload部分不能存放敏感的密碼信息等等,還可以進(jìn)行優(yōu)化。

項(xiàng)目代碼:https://gitee.com/yanglingcong/jwt-demo

到此這篇關(guān)于實(shí)戰(zhàn)SpringBoot集成JWT實(shí)現(xiàn)token驗(yàn)證的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java實(shí)戰(zhàn)之制作在線音樂網(wǎng)站

    Java實(shí)戰(zhàn)之制作在線音樂網(wǎng)站

    這篇文章主要介紹了如何通過Java實(shí)現(xiàn)一個(gè)精美風(fēng)的在線音樂網(wǎng)站,文章采用到了JSP、JQuery、Ajax等技術(shù),感興趣的小伙伴可以了解一下
    2022-02-02
  • JDBC操作數(shù)據(jù)庫(kù)的增加、刪除、更新、查找實(shí)例分析

    JDBC操作數(shù)據(jù)庫(kù)的增加、刪除、更新、查找實(shí)例分析

    這篇文章主要介紹了JDBC操作數(shù)據(jù)庫(kù)的增加、刪除、更新、查找方法,以完整實(shí)例形式分析了Java基于JDBC連接數(shù)據(jù)庫(kù)及進(jìn)行數(shù)據(jù)的增刪改查等技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-10-10
  • MybatisPlus代碼生成器的使用方法詳解

    MybatisPlus代碼生成器的使用方法詳解

    在這里我將展示如何自動(dòng)生成實(shí)體類、控制層、服務(wù)層、mapper等代碼,這些基礎(chǔ)的代碼全部不需要我們手動(dòng)創(chuàng)建,由MybatisPlus自動(dòng)幫我們完成,我們只需要告訴MybatisPlus怎么生成這些代碼就可以了,在此之前我們需要配置好測(cè)試的環(huán)境,數(shù)據(jù)庫(kù)和表數(shù)據(jù) ,需要的朋友可以參考下
    2021-06-06
  • JavaScript中new運(yùn)算符的實(shí)現(xiàn)過程解析

    JavaScript中new運(yùn)算符的實(shí)現(xiàn)過程解析

    這篇文章主要介紹了JavaScript中new運(yùn)算符的實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • SpringBoot之Banner的使用示例

    SpringBoot之Banner的使用示例

    本篇文章主要介紹了SpringBoot之Banner的使用示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-11-11
  • java~springboot~ibatis數(shù)組in查詢的實(shí)現(xiàn)方法

    java~springboot~ibatis數(shù)組in查詢的實(shí)現(xiàn)方法

    這篇文章主要介紹了java~springboot~ibatis數(shù)組in查詢的實(shí)現(xiàn)方法,需要的朋友可以參考下
    2018-09-09
  • SpringBoot開發(fā)技巧啟動(dòng)時(shí)配置校驗(yàn)實(shí)現(xiàn)示例

    SpringBoot開發(fā)技巧啟動(dòng)時(shí)配置校驗(yàn)實(shí)現(xiàn)示例

    這篇文章主要為大家介紹了SpringBoot開發(fā)在啟動(dòng)時(shí)自動(dòng)配置校驗(yàn)的實(shí)現(xiàn)示例及原理解析,有需要的朋友可以借鑒參考下希望能夠有所幫助
    2021-10-10
  • 一篇文章帶你詳解Spring的概述

    一篇文章帶你詳解Spring的概述

    這篇文章主要為大家介紹了Spring的概述,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • SpringCloud HystrixDashboard服務(wù)監(jiān)控詳解

    SpringCloud HystrixDashboard服務(wù)監(jiān)控詳解

    Hystrix Dashboard 是Spring Cloud中查看Hystrix實(shí)例執(zhí)行情況的一種儀表盤組件,支持查看單個(gè)實(shí)例和查看集群實(shí)例,本文將對(duì)其服務(wù)監(jiān)控學(xué)習(xí)
    2022-11-11
  • JavaGUI實(shí)現(xiàn)隨機(jī)單詞答題游戲

    JavaGUI實(shí)現(xiàn)隨機(jī)單詞答題游戲

    這篇文章主要為大家詳細(xì)介紹了JavaGUI實(shí)現(xiàn)隨機(jī)單詞答題游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12

最新評(píng)論

钟山县| 东乌珠穆沁旗| 郯城县| 和田市| 洛南县| 洪洞县| 合水县| 新昌县| 曲水县| 泸西县| 陈巴尔虎旗| 嘉黎县| 扬州市| 穆棱市| 章丘市| 渑池县| 渑池县| 泽普县| 石屏县| 吉水县| 增城市| 宣城市| 苏州市| 阿荣旗| 上高县| 辉县市| 鹰潭市| 嘉义县| 龙口市| 夹江县| 高清| 南部县| 奇台县| 广丰县| 达孜县| 利川市| 澄城县| 临江市| 平陆县| 松滋市| 玛沁县|