Spring Boot使用JWT認(rèn)證

JSON Web Token(JWT)是一個(gè)非常輕巧的規(guī)范。這個(gè)規(guī)范允許我們使用JWT在用戶和服務(wù)器之間傳遞安全可靠的信息。
JWT的組成
一個(gè)JWT實(shí)際上就是一個(gè)字符串,它由三部分組成,頭部、載荷與簽名。簡單說明就到此為止,下面我們簡單介紹如何使用JWT。
1、引入相關(guān)的包
在pom.xml中引入JWT的包,和SpringMVC包。

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.8.0</version>
        </dependency>

2、定義加密的秘鑰
這個(gè)可以省略,可以使用用戶的密碼作為加密秘鑰。

public class ConstantKey {
    public static final String PICEA_JWT_KEY = "spring-boot-jwt-key~#^";
}

3、直接在控制類里面引入JWT生成方法
主要說明JWT.create()方法,注釋中說明了
withAudience(name)// 將 user id 保存到 token 里面
withExpiresAt(new Date(System.currentTimeMillis() + 2 * 60 * 1000))//定義token的有效期
sign(Algorithm.HMAC256(ConstantKey.PICEA_JWT_KEY));// 加密秘鑰,也可以使用用戶保持在數(shù)據(jù)庫中的密碼字符串。
最后我們得到的JWT,其實(shí)是如下一串字符串。
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJ6aGFuZ3NhbiIsImV4cCI6MTU1NTQ5MzI0OH0.FZISiYvyLJcrARe0nC8umMZ_MdR0YMkjMXI2mXYUncE

控制類的代碼如下。

@RestController
public class PiceaContoller {

    @RequestMapping("/login")
    public Object login(String name, String password) throws Exception {
        /**
         * 這里為了簡單,就不驗(yàn)證用戶名和密碼的正確性了,實(shí)際驗(yàn)證跟其他的方式一樣,
         *         就是比對一下輸入的用戶名密碼跟數(shù)據(jù)的數(shù)據(jù)是否一樣
         */
        String token = "";
        token = JWT.create()
                .withAudience(name)// 將 user id 保存到 token 里面
                .withExpiresAt(new Date(System.currentTimeMillis() + 2 * 60 * 1000))//定義token的有效期
                .sign(Algorithm.HMAC256(ConstantKey.PICEA_JWT_KEY));// 加密秘鑰,也可以使用用戶保持在數(shù)據(jù)庫中的密碼字符串
        return token;
    }

    @RequestMapping("/queryPicea")
    public String queryPicea()  {
        String ret = "通過驗(yàn)證";
        return ret;
    }
}

4、使用攔截器實(shí)現(xiàn)認(rèn)證
如果你對攔截器還不明白,請移步Spring Boot使用處理器攔截器HandlerInterceptor。

public class AuthenticationInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception {
        String token = httpServletRequest.getHeader("token");// 從 http 請求頭中取出 token
        // 如果不是映射到方法直接通過
        if(!(object instanceof HandlerMethod)){
            return true;
        }
        HandlerMethod handlerMethod=(HandlerMethod)object;
        Method method=handlerMethod.getMethod();
        //檢查方法名是否是“l(fā)ogin”如果是則跳過,也可以加注解,用注解過濾不需要權(quán)限的方法
        if ("login".equals(method.getName())) {
           return true;
        }
        // 執(zhí)行認(rèn)證
        if (token == null) {
            throw new RuntimeException("無token,請重新登錄");
        }
        // 獲取 token 中的 name
        String name;
        try {
            name = JWT.decode(token).getAudience().get(0);
        } catch (JWTDecodeException j) {
            throw new RuntimeException("401");
        }
        // 驗(yàn)證 token
        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(ConstantKey.PICEA_JWT_KEY)).build();
        try {
            jwtVerifier.verify(token);
        } catch (JWTVerificationException e) {
            throw new RuntimeException("401");
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}

5、建立InterceptorConfig注冊攔截器

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(authenticationInterceptor())
                .addPathPatterns("/**");
    }

    @Bean
    public AuthenticationInterceptor authenticationInterceptor() {
        return new AuthenticationInterceptor();
    }
}

6、進(jìn)行功能測試
首先我們之間執(zhí)行查詢,這里測試需要使用到post工具了,我用的是ApiPost。
1)無token的情況,直接請求查詢


Spring-boot-jwt-query.png

2)登錄,獲得token


Spring-boot-jwt-token.png

3)帶著token請求
Spring-boot-jwt-query-token.png

其它注意

本文章樣例:
工程名:spring-boot-jwt
GitHub:https://github.com/zzyjb/SpringBootLearning

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容