欢迎关注方志朋的博客,回复”666“获面试宝典

jwt是什么?

JWTs是JSON对象的编码表示。JSON对象由零或多个名称/值对组成,其中名称为字符串,值为任意JSON值。JWT有助于在clear(例如在URL中)发送这样的信息,可以被信任为不可读(即加密的)、不可修改的(即签名)和URL - safe(即Base64编码的)。

jwt的组成

  • Header: 标题包含了令牌的元数据,并且在最小包含签名和/或加密算法的类型

  • Claims: Claims包含您想要签署的任何信息

  • JSON Web Signature (JWS): 在header中指定的使用该算法的数字签名和声明

例如:

Header:{"alg": "HS256","typ": "JWT"
}Claims:{"sub": "1234567890","name": "John Doe","admin": true
}Signature:base64UrlEncode(Header) + "." + base64UrlEncode(Claims),

加密生成的token:

如何保证 JWT 安全

有很多库可以帮助您创建和验证JWT,但是当使用JWT时,仍然可以做一些事情来限制您的安全风险。在您信任JWT中的任何信息之前,请始终验证签名。这应该是给定的。

换句话说,如果您正在传递一个秘密签名密钥到验证签名的方法,并且签名算法被设置为“none”,那么它应该失败验证。

确保签名的秘密签名,用于计算和验证签名。秘密签名密钥只能由发行者和消费者访问,不能在这两方之外访问。

不要在JWT中包含任何敏感数据。这些令牌通常是用来防止操作(未加密)的,因此索赔中的数据可以很容易地解码和读取。

如果您担心重播攻击,包括一个nonce(jti索赔)、过期时间(exp索赔)和创建时间(iat索赔)。这些在JWT规范中定义得很好。

推荐:Java进阶视频资源

jwt的框架:JJWT

JJWT是一个提供端到端的JWT创建和验证的Java库。永远免费和开源(Apache License,版本2.0),JJWT很容易使用和理解。它被设计成一个以建筑为中心的流畅界面,隐藏了它的大部分复杂性。

  • JJWT的目标是最容易使用和理解用于在JVM上创建和验证JSON Web令牌(JWTs)的库。

  • JJWT是基于JWT、JWS、JWE、JWK和JWA RFC规范的Java实现。

  • JJWT还添加了一些不属于规范的便利扩展,比如JWT压缩和索赔强制。

规范兼容:

  • 创建和解析明文压缩JWTs

  • 创建、解析和验证所有标准JWS算法的数字签名紧凑JWTs(又称JWSs):

  • HS256: HMAC using SHA-256

  • HS384: HMAC using SHA-384

  • HS512: HMAC using SHA-512

  • RS256: RSASSA-PKCS-v1_5 using SHA-256

  • RS384: RSASSA-PKCS-v1_5 using SHA-384

  • RS512: RSASSA-PKCS-v1_5 using SHA-512

  • PS256: RSASSA-PSS using SHA-256 and MGF1 with SHA-256

  • PS384: RSASSA-PSS using SHA-384 and MGF1 with SHA-384

  • PS512: RSASSA-PSS using SHA-512 and MGF1 with SHA-512

  • ES256: ECDSA using P-256 and SHA-256

  • ES384: ECDSA using P-384 and SHA-384

  • ES512: ECDSA using P-521 and SHA-512

这里以github上的demo演示,理解原理,集成到自己项目中即可。

应用采用 spring boot + angular + jwt

结构图

Maven 引进 : pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.nibado.example</groupId><artifactId>jwt-angular-spring</artifactId><version>0.0.2-SNAPSHOT</version><properties><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target><commons.io.version>2.4</commons.io.version><jjwt.version>0.6.0</jjwt.version><junit.version>4.12</junit.version><spring.boot.version>1.5.3.RELEASE</spring.boot.version></properties><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>${spring.boot.version}</version><executions><execution><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>${spring.boot.version}</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>${commons.io.version}</version></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>${jjwt.version}</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>${junit.version}</version></dependency></dependencies>
</project>

WebApplication.java

package com.nibado.example.jwtangspr;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;@EnableAutoConfiguration
@ComponentScan
@Configuration
public class WebApplication {//过滤器@Beanpublic FilterRegistrationBean jwtFilter() {final FilterRegistrationBean registrationBean = new FilterRegistrationBean();registrationBean.setFilter(new JwtFilter());registrationBean.addUrlPatterns("/api/*");return registrationBean;}public static void main(final String[] args) throws Exception {SpringApplication.run(WebApplication.class, args);}}

JwtFilter.java

package com.nibado.example.jwtangspr;import java.io.IOException;import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;import org.springframework.web.filter.GenericFilterBean;import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureException;public class JwtFilter extends GenericFilterBean {@Overridepublic void doFilter(final ServletRequest req,final ServletResponse res,final FilterChain chain) throws IOException, ServletException {final HttpServletRequest request = (HttpServletRequest) req;//客户端将token封装在请求头中,格式为(Bearer后加空格):Authorization:Bearer +tokenfinal String authHeader = request.getHeader("Authorization");if (authHeader == null || !authHeader.startsWith("Bearer ")) {throw new ServletException("Missing or invalid Authorization header.");}//去除Bearer 后部分final String token = authHeader.substring(7);try {//解密token,拿到里面的对象claimsfinal Claims claims = Jwts.parser().setSigningKey("secretkey").parseClaimsJws(token).getBody();//将对象传递给下一个请求request.setAttribute("claims", claims);}catch (final SignatureException e) {throw new ServletException("Invalid token.");}chain.doFilter(req, res);}}

UserController.java

package com.nibado.example.jwtangspr;import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import javax.servlet.ServletException;import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;@RestController
@RequestMapping("/user")
public class UserController {//这里模拟数据库private final Map<String, List<String>> userDb = new HashMap<>();@SuppressWarnings("unused")private static class UserLogin {public String name;public String password;}public UserController() {userDb.put("tom", Arrays.asList("user"));userDb.put("wen", Arrays.asList("user", "admin"));}/*以上是模拟数据库,并往数据库插入tom和sally两条记录*/@RequestMapping(value = "login", method = RequestMethod.POST)public LoginResponse login(@RequestBody final UserLogin login)throws ServletException {if (login.name == null || !userDb.containsKey(login.name)) {throw new ServletException("Invalid login");}//加密生成tokenreturn new LoginResponse(Jwts.builder().setSubject(login.name).claim("roles", userDb.get(login.name)).setIssuedAt(new Date()).signWith(SignatureAlgorithm.HS256, "secretkey").compact());}@SuppressWarnings("unused")private static class LoginResponse {public String token;public LoginResponse(final String token) {this.token = token;}}
}

ApiController.java

package com.nibado.example.jwtangspr;import io.jsonwebtoken.Claims;import java.util.List;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/api")
public class ApiController {@SuppressWarnings("unchecked")@RequestMapping(value = "role/{role}", method = RequestMethod.GET)public Boolean login(@PathVariable final String role,final HttpServletRequest request) throws ServletException {final Claims claims = (Claims) request.getAttribute("claims");return ((List<String>) claims.get("roles")).contains(role);}
}

index.html

<!doctype html>
<html ng-app="myApp">
<head><meta charset="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/><title>JSON Web Token / AngularJS / Spring Boot example</title><meta name="description" content=""><meta name="viewport" content="width=device-width"><link rel="stylesheet" href="libs/bootstrap/css/bootstrap.css"><script src="libs/jquery/jquery.js"></script><script src="libs/bootstrap/js/bootstrap.js"></script><script src="libs/angular/angular.js"></script><script src="app.js"></script>
</head>
<body>
<div class="container" ng-controller='MainCtrl'><h1>{{greeting}}</h1><div ng-show="!loggedIn()">Please log in (tom and sally are valid names)</br><form ng-submit="login()">Username: <input type="text" ng-model="userName"/><span><input type="submit" value="Login"/></form></div><div class="alert alert-danger" role="alert" ng-show="error.data.message"><span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span><span class="sr-only">Error:</span>{{error.data.message}}</div> <div ng-show="loggedIn()"><div class="row"><div class="col-md-6"><h3><span class="label label-success">Success!</span> Welcome {{userName}}</h3><a href ng-click="logout()">(logout)</a></div><div class="col-md-4"><div class="row header"><div class="col-sm-4">{{userName}} is a</div></div><div class="row"><div class="col-sm-2">User</div><div class="col-sm-2"><span class="glyphicon glyphicon-ok" aria-hidden="true" ng-show="roleUser"></span></div></div><div class="row"><div class="col-sm-2">Admin</div><div class="col-sm-2"><span class="glyphicon glyphicon-ok" aria-hidden="true" ng-show="roleAdmin"></span></div></div> <div class="row"><div class="col-sm-2">Foo</div><div class="col-sm-2"><span class="glyphicon glyphicon-ok" aria-hidden="true" ng-show="roleFoo"></span></div></div>    </div></div></div>
</div>
</body>
</html>

app.js

var appModule = angular.module('myApp', []);appModule.controller('MainCtrl', ['mainService','$scope','$http',function(mainService, $scope, $http) {$scope.greeting = 'Welcome to the JSON Web Token / AngularJR / Spring example!';$scope.token = null;$scope.error = null;$scope.roleUser = false;$scope.roleAdmin = false;$scope.roleFoo = false;$scope.login = function() {$scope.error = null;mainService.login($scope.userName).then(function(token) {$scope.token = token;$http.defaults.headers.common.Authorization = 'Bearer ' + token;$scope.checkRoles();},function(error){$scope.error = error$scope.userName = '';});}$scope.checkRoles = function() {mainService.hasRole('user').then(function(user) {$scope.roleUser = user});mainService.hasRole('admin').then(function(admin) {$scope.roleAdmin = admin});mainService.hasRole('foo').then(function(foo) {$scope.roleFoo = foo});}$scope.logout = function() {$scope.userName = '';$scope.token = null;$http.defaults.headers.common.Authorization = '';}$scope.loggedIn = function() {return $scope.token !== null;}} ]);appModule.service('mainService', function($http) {return {login : function(username) {return $http.post('/user/login', {name: username}).then(function(response) {return response.data.token;});},hasRole : function(role) {return $http.get('/api/role/' + role).then(function(response){console.log(response);return response.data;});}};
});

运行应用

效果

(感谢阅读,希望对你所有帮助)

来源:blog.csdn.net/change_on/

article/details/76279441

热门内容:
  • MySQL 8.0 可以操作 JSON 了,牛逼。。。

  • 如何写出让同事无法维护的代码?

  • 抖音的服务器究竟有多大?

  • 重磅消息:Spring 6 和Spring Boot 3

  • 有个程序员老公有多爽???

最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。
获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。

明天见(。・ω・。)ノ♡

还在直接用JWT做鉴权?JJWT真香相关推荐

  1. 还在直接用 JWT 做鉴权?JJWT 真香

    点击关注公众号,回复"1024"获取2TB学习资源! jwt是什么? JWTs是JSON对象的编码表示.JSON对象由零或多个名称/值对组成,其中名称为字符串,值为任意JSON值. ...

  2. Tornado做鉴权服务性能实践

    一. Torado实现鉴权服务 使用python的第三方jwt做鉴权服务, 生产token代码: def create_token(self, userId, product, level):payl ...

  3. SpringBoot使用security和jwt进行鉴权设计

    一.使用security默认登录接口登录成功.生成token.返回前段 项目的结构如下: 1.引入jar包 <dependency><groupId>org.springfra ...

  4. Spring security+jwt服务鉴权完整代码

    将代码下载到本地, 直接以包的形式添加到项目中就可以实现鉴权功能了. <!-- spring-security 和 jwt start --><dependency><g ...

  5. java 鉴黄_真香,我把百万鉴黄服务源码开源了

    前言 最近某云审查的比较严,图床上的内容也无奈关闭了,有兴趣的小伙伴可以使用炒鸡工具箱自行搭建.今儿跟大家分享一下之前自建鉴黄服务的这个流程顺便分享一下相关源码. 图床架构 鉴黄流程 代码案例 建议有 ...

  6. 50套可视化报表模板直接用,做报告不用愁了!快收藏

    总有人头疼:报表怎么做?数据怎么展现给领导才是最合适的?年终总结怎么让人眼前一亮? 用Excel吧,太低端了,而且是真的丑,万一被pass不就惨了? 用python自动化吧,不会代码,不给自己找事了. ...

  7. 计算机 术语库 excel,Trados直接用Excel做术语库

    术语库都不用制作,您可以直接在Trados中加载Excel术语表作为术语库,不仅操作极其方便,而且极大地简化了术语加载.更新过程.这一切,我们只需要使用完全免费的TermExcelerator插件即可 ...

  8. 还在网上找Demo?这个Java项目真香!

    我前几天专门去网上搜集项目,打算找一些分享给大家用来实践. 但找了一圈发现,网上的项目都比较旧,业务也有些过时,再有就是一些特别大型的项目,不适合初学者做. 不过,我最终还是发现了1个免费的Java训 ...

  9. JWT详解、JJWT使用、token 令牌

    前言 在正式讲解JWT之前,我们先重温一下用户身份认证相关的一些概念: 有状态登录(session认证) 服务器当中记录每一次的登录信息,从而根据客户端发送的数据来判断登录过来的用户是否合法. 缺点: ...

最新文章

  1. 摆脱 FM!这些推荐系统模型真香
  2. python第三方库使用文档_python 的第三方库的使用
  3. CSS基础(part15)--元素的隐藏与显示
  4. PropertyGrid控件 分类(Category)及属性(Property)排序
  5. c#象棋程序_C ++程序确定象棋方块的颜色
  6. 在Android中实现异步任务
  7. 【LeetCode 剑指offer刷题】动态规划与贪婪法题7:47:礼物的最大价值
  8. Regex Tester 安装教程
  9. 谷歌免费域名邮箱申请全解
  10. 你还因为缺“Java项目经验”找不到工作?适合应届生的20个“项目经验”送给你
  11. 【CAN】CAN的比特率和波特率
  12. c语言程序设计基础谭成予答案,c语言程序设计基础谭成予答案
  13. JavaScript之显示和隐藏图片
  14. win10 怎么由豆沙绿恢复为默认的颜色
  15. 品牌如何赋能加盟商,攻克时艰
  16. Revit二次开发——设备自动接管插件的开发思路(入门实例教程)
  17. 【Lintcode】1647. Path Search
  18. 三极管工作原理分析,精辟、透彻
  19. word图文混排复制到eWebEditor图片不显示
  20. jmeter中控制器的使用

热门文章

  1. Oracle总结第二篇【视图、索引、事务、用户权限、批量操作】
  2. go1.8之安装配置
  3. CSS jQuery制作漂亮的文字模糊效果
  4. japid-controller自动绑定的数据类型
  5. [JS-JQuery]基础
  6. 【组队学习】【33期】动手学数据分析
  7. Datawhale组队学习周报(第041周)
  8. 【青少年编程】【三级】计算成绩总和
  9. 如何利用 C# 爬取带 Token 验证的网站数据?
  10. 【通俗理解线性代数】 -- 理解行列式