免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
json-web-token(JWT)
JWT是什么


JWT的全稱為json web token。不要把它想得多么高深,其實就是一種生成token的方式。一般我們訪問一個系統(tǒng)的流程就是:請求登錄接口,該接口會返回一個token,請求其他接口都要帶上token,token驗證通過才能訪問成功,而JWT可以理解為就是生成token的一種機制。

JWT怎么用

1、添加jwt的依賴:

<!-- JWT -->
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.4.0</version>
</dependency>

2、新建一個TokenService,用來生成token:

@Service
public class TokenService {
    // token過期時間5分鐘
    private static final long EXPIRE_TIME = (60 * 1000 * 5);

    public String getToken(User user) {
        return JWT.create()
                // 需要放入token中的信息
                .withAudience(user.getId())
                // 設置token過期時間
                .withExpiresAt(new Date(System.currentTimeMillis() + EXPIRE_TIME))
                // 用戶密碼當作密鑰
                .sign(Algorithm.HMAC256(user.getPassword()));
    }
}

User類就是一個普通的pojo,這里就不把代碼貼出來了。這個getToken方法表示將用戶的密碼作為密鑰,把用戶的id放進token中,設置token過期時間為5分鐘。

3、新建兩個注解,一個注解表示需要驗證,另一個表示跳過驗證:

  • 需要驗證:

//可以作用在方法,類和接口上
@Target({ElementType.METHOD, ElementType.TYPE})
//編譯器會將SkipToken的信息保存在虛擬機中
@Retention(RetentionPolicy.RUNTIME)
public @interface NeedToken {
    // required 屬性默認值為true
    boolean required() default true;
}
  • 跳過驗證:

@Target({ElementType.METHODElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface SkipToken {
    boolean required() default true;
}

4、新建一個AuthInterceptor類,用于攔截請求:

public class AuthInterceptor implements HandlerInterceptor {
    @Autowired
    private UserService userService;

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,Object object) {
        // 從 http 請求頭中取出 token
        String token = httpServletRequest.getHeader("token");
        // 只攔截方法,不是方法直接返回true
        if (!(object instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) object;
        Method method = handlerMethod.getMethod();
        // 有SkipToken注解的直接跳過認證
        if (method.isAnnotationPresent(SkipToken.class)) {
            SkipToken skipToken = method.getAnnotation(SkipToken.class);
            if (skipToken.required()) {
                return true;
            }
        }
        // 有NeedToken注解的就進行認證
        if (method.isAnnotationPresent(NeedToken.class)) {
            NeedToken needToken = method.getAnnotation(NeedToken.class);
            if (needToken.required()) {
                if (token == null) {
                    throw new RuntimeException("無token,請重新登錄");
                }
                // 獲取 token 中的 userId
                String userId;
                try {
                    userId = JWT.decode(token).getAudience().get(0);
                } catch (JWTDecodeException j) {
                    throw new RuntimeException("401");
                }
                // 根據(jù)userId查詢數(shù)據(jù)庫
                User user = userService.findUserById(userId);
                if (user == null) {
                    throw new RuntimeException("用戶不存在,請重新登錄");
                }
                // 用查出來的user的密碼去校驗token
                JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
                try {
                    // 沒發(fā)生異常就表示校驗通過
                    jwtVerifier.verify(token);
                } catch (JWTVerificationException e) {
                    throw new RuntimeException("401");
                }
                return true;
            }
        }
        return true;
    }

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

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

這個攔截器的處理邏輯就是:

  • 只攔截方法,如果不是方法,就放行;

  • 如果攔截的方法有@SkipToken注解,放行;

  • 如果攔截的方法有@NeedToken注解,則需要驗證token;

  • 取出請求頭中的token,拿出token中的userId,根據(jù)此userId去數(shù)據(jù)庫查詢對應的記錄;

  • 再將查出來的user的password去驗證token,驗證成功則放行;

  • 如果沒有@NeedToken也沒有@SkipToken注解的,也放行。

5、新建一個InterceptorConfig類,將我們上面寫的攔截器配置到spring容器中去:

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(authInterceptor())
                .addPathPatterns("/**");   
    }
    @Bean
    public AuthInterceptor authInterceptor() {
        return new AuthInterceptor();
    }
}

6、在controller中的用法:

@RestController
@RequestMapping("api")
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private TokenService tokenService;

    @SkipToken
    @PostMapping("/user")
    public JsonResult login(User user){
        User dbUser = userService.findForLogin(user);
        if (dbUser == null){
            return new JsonResult(200"用戶名或密碼錯誤"null);
        } else {
            String token = tokenService.getToken(dbUser);
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("token", token);
            resultMap.put("user", dbUser);
            return new JsonResult(200"登錄成功", resultMap);
        }
    }

    @NeedToken
    @GetMapping("/getMessage")
    public String getMessage(){
        return "你已通過驗證";
    }

    @SkipToken
    @GetMapping("/noToken")
    public String noToken() {
        return "無需token訪問";
    }
}

以上就是JWT的用法,其實在實際生產(chǎn)中一般會配合shiro使用。

-java開發(fā)那些事兒-
本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
詳細!SpringBoot整合SpringSecurity實現(xiàn)JWT認證
Shiro JWT Spring Boot Restful 簡易教程
干貨|一個案例學會Spring Security 中使用 JWT!
SpringBoot JWT完成token驗證
Spring Boot 訪問安全之認證和鑒權(quán)詳解
spring boot2整合shiro安全框架實現(xiàn)前后端分離的JWT token登錄驗證
更多類似文章 >>
生活服務
分享 收藏 導長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服