日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

jwt获取token_JWT实现token认证

發布時間:2023/12/10 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jwt获取token_JWT实现token认证 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.JWT是什么?

Json Web Token(JWT)是目前比較流行的跨域認證解決方案,是一種基于JSON的開發標準,由于數據是可以經過簽名加密的,比較安全可靠,一般用于前端和服務器之間傳遞信息,也可以用在移動端和后臺傳遞認證信息。

2.JWT的組成

讓我們先來看看jwt的實際例子:

Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2wiOiJST0xFXzEiLCJpc3MiOiJTbmFpbENsaW1iIiwiaWF0IjoxNTk1OTkzMDQwLCJzdWIiOiIxNTAwMDAwMDAwMCIsImV4cCI6MTU5NjU5Nzg0MH0.Wxet2qPG1ajyG9CcQCN29gfKJzal0vCmQSXrwAgQwcI

我們可以看到,這個JWT包含3部分,是由“.”號分開的,Bearer是jwt中的一種前綴規范。

第一部分是Header:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

第二部分是Payload:

eyJyb2wiOiJST0xFXzEiLCJpc3MiOiJTbmFpbENsaW1iIiwiaWF0IjoxNTk2MDAzODM4LCJzdWIiOiIxNTAwMDAwMDAwMCIsImV4cCI6MTU5NjYwODYzOH0

第三方部分是簽名Signature:

MJmTSGBM9wRVOY40ORZuSGpT7FQNUcD2JlJxL0K0-YM

3.JWT的流程

先上圖:

  • 客戶端登錄接口輸入用戶名和密碼提交到服務器;

  • 服務器端校驗用戶名和密碼,校驗通過則創建一個JWT;

  • 服務器端返回該JWT給客戶端;

  • 客戶端每請求一次接口在Headers中帶上返回的JWT;

  • JWT自身的算法校驗該JWT;

  • 如果校驗通過,操作DB,返回數據;反之返回狀態碼和錯誤信息。

  • 4.SpringBoot集成JWT,代碼實現

    引入jwt的依賴庫:

    <dependency> <groupId>io.jsonwebtokengroupId> <artifactId>jjwt-apiartifactId> <version>0.10.7version> dependency> <dependency> <groupId>io.jsonwebtokengroupId> <artifactId>jjwt-implartifactId> <version>0.10.7version> <scope>runtimescope> dependency> <dependency> <groupId>io.jsonwebtokengroupId> <artifactId>jjwt-jacksonartifactId> <version>0.10.7version> <scope>runtimescope> dependency>

    JwtTokenUtils類:用于生成token

    /**?*?@author?kevincow */public class JwtTokenUtils { /** * 生成足夠的安全隨機密鑰,以適合符合規范的簽名 */ private static byte[] apiKeySecretBytes = Base64.getDecoder().decode(SecurityConstants.JWT_SECRET_KEY); private static SecretKey secretKey = Keys.hmacShaKeyFor(apiKeySecretBytes); public static String createToken(String username, List<String> roles) { long expiration = SecurityConstants.EXPIRATION_REMEMBER; String tokenPrefix = Jwts.builder() .setHeaderParam("typ", SecurityConstants.TOKEN_TYPE) .signWith(secretKey, SignatureAlgorithm.HS256) .claim(SecurityConstants.ROLE_CLAIMS, String.join(",", roles)) .setIssuer("SnailClimb") .setIssuedAt(new Date()) .setSubject(username) .setExpiration(new Date(System.currentTimeMillis() + expiration * 1000)) .compact(); return SecurityConstants.TOKEN_PREFIX + tokenPrefix; }}

    接下來需要寫一個過濾器去實現token的校驗功能:

    /** * 實現token的校驗功能 * * 過濾器處理所有HTTP請求,并檢查是否存在帶有正確令牌的Authorization標頭。例如,如果令牌未過期或簽名密鑰正確。 *?*?@author?kevincow */public class JWTAuthorizationFilter extends BasicAuthenticationFilter { private static final Logger logger = Logger.getLogger(JWTAuthorizationFilter.class.getName()); public JWTAuthorizationFilter(AuthenticationManager authenticationManager) { super(authenticationManager); } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { logger.info("token"+request.getHeader(SecurityConstants.TOKEN_HEADER)); String authorization = request.getHeader(SecurityConstants.TOKEN_HEADER); // 如果請求頭中沒有token信息則直接放行了 if (authorization == null || !authorization.startsWith(SecurityConstants.TOKEN_PREFIX)) { chain.doFilter(request, response); return; } // 如果請求頭中有token,則進行解析,并且設置授權信息 SecurityContextHolder.getContext().setAuthentication(getAuthentication(authorization)); super.doFilterInternal(request, response, chain); } /** * 獲取用戶認證信息 Authentication */ private UsernamePasswordAuthenticationToken getAuthentication(String authorization) { String token = authorization.replace(SecurityConstants.TOKEN_PREFIX, ""); try { String username = JwtTokenUtils.getUsernameByToken(token); logger.info("checking username:" + username); // 通過 token 獲取用戶具有的角色 List userRolesByToken = JwtTokenUtils.getUserRolesByToken(token); if (!StringUtils.isEmpty(username)) { return new UsernamePasswordAuthenticationToken(username, null, userRolesByToken); } } catch (SignatureException | ExpiredJwtException | MalformedJwtException | IllegalArgumentException exception) { logger.warning("Request to parse JWT with invalid signature . Detail : " + exception.getMessage()); } return null; }}

    最后寫業務實現代碼了(這里只展示控制層代碼,業務代碼就不一一贅述)

    /**?????*?微信端登錄接口,在header中帶上token * * @param userName * @param passWord?????*?@return?是否登錄成功 */????@ApiOperation(value?=?"用戶登錄成功之后,在header中帶上token",????????????notes?=?"校驗用戶名密碼,校驗完成之后,在header中帶上token",?httpMethod?=?"GET")????@PostMapping("/whetherIsSysUser")????public?SuccessResponse?whetherRegister(@ApiParam("用戶名")?@RequestParam?String?userName,???????????????????????????????????????????@ApiParam("密碼")?@RequestParam?String?passWord, HttpServletResponse response) { try { User user = userService.whetherRegister(userName, passWord); if (StringUtils.isEmpty(user)) { return SuccessResponse.of(false, "該用戶未注冊"); } JwtUser jwtUser = new JwtUser(user); List roles = jwtUser.getAuthorities() .stream() .map(GrantedAuthority::getAuthority) .collect(Collectors.toList()); String token = JwtTokenUtils.createToken(user.getPhone(), roles); // Http Response Header 中返回 Token response.setHeader(SecurityConstants.TOKEN_HEADER, token); } catch (RuntimeException e) { e.printStackTrace(); return SuccessResponse.of(false, "該用戶未注冊"); } return SuccessResponse.of(true); }

    至此,代碼實現部分差不多就完成了。接下來我們看下效果:

    上圖可以看到,登錄接口用戶名密碼校驗通過之后在headers中返回了Authorization。

    然后當客戶端請求其他接口并在請求頭帶上登錄時返回的Authorization,就能正常響應了。

    如果沒有帶上Authorization呢?那么會報一個錯。

    { "timestamp": "2020-07-29 15:38:23", "status": 401, "error": "Unauthorized", "message": "Full authentication is required to access this resource", "path": "/wx/users/showNewVersion"}

    以上就差不多是jwt的整個流程了。

    5.總結

    ????從特點中看優點:

    • JSON的通用性,決定了JWT是個跨語言的技術;

    • JWT token對于sessionid的方案來說,JWT可以攜帶任何我們想要用到的信息;

    • 安全性高,防止token偽造和篡改;

    • JWT token是自校驗的形式,不需要任何其他請求和數據庫操作,使我們系統管理會話更高效;

    • JWT不需要在服務端保存會話信息, 所以它易于應用的擴展

    ????從特點中找缺點:

    • 一旦成功簽發JWT token,無法手動將其過期;

    • 在token簽發后的有效時間內,JWT無法做到及時獲取最新數據,例如修改密碼后無感知;

    • 存儲空間、網絡流量開銷更大;

    • 為了安全,JWT需要使用https協議,以免token泄露

    以上。

    我是凱文cow,念念不忘,必有回響。

    總結

    以上是生活随笔為你收集整理的jwt获取token_JWT实现token认证的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。