jwttoken解码_使用 JSON WEB TOKEN (jwt) 验证
一、什么JSON Web Tokens?
JSON Web Tokens是一种开放的行业标准 RFC 7519方法,用于在双方之间安全地表示索赔。
JWT.IO允许您解码,验证和生成JWT。其中。JWT 支持任何语言的解码。
二、JWT 的结构
JWT由三部分组成:
1.Header :头信息
标头通常由两部分组成:令牌的类型,即JWT,以及正在使用的签名算法
如:{ "alg": "HS256", "typ": "JWT"}
然后,这个JSON被编码为Base64Url,形成JWT的第一部分。
2.Payload :有效载荷
令牌的第二部分是有效负载,其中包含声明。声明是关于实体(通常是用户)和其他数据的声明。
示例有效负载可以是:{ "sub": "1234567890", "name": "John Doe", "admin": true}
然后,有效负载经过Base64Url编码,形成JSON Web令牌的第二部分。由于JWT 支持任何语言的解码,所以不要在Payload 中放置重要信息
3.Signature :签名
如:HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
签名由三部分组成,base64编码后的表头、base64编码后的有效载荷和秘钥,三者中间由 '.' 字符连接。这里举例的是采用HMACSHA256算法加密的。
其中secret秘钥是注册后创建app之后生成的(此秘钥非常重要,不要告诉别人哟)。
三、代码实现(以net core 为例):
1.首先引用 Microsoft.IdentityModel.Tokens.dll。net core 2.1版本中内置了这个库,其他版本要引用。
2.为了方便,我把整个jwt结构写了配置,并在项目中引用。
创建了对应的配置节点实体:using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace fwt.Models
{
///
/// jwt
///
public class JWTTokenModel
{
public JWTHeader header { get; set; }
public JWTPayLoad payLoad { get; set; }
public string secret { get; set; }
}
///
/// header
///
public class JWTHeader
{
public string alg { get; set; }
public string typ { get; set; }
}
///
/// payLoad
///
public class JWTPayLoad
{
public string iss { get; set; }
public string aud { get; set; }
public string age { get; set; }
public string sub { get; set; }
public long nbf { get; set; }
public long exp { get; set; }
}
}
通过构造函数依赖注入,在Controller中获取配置信息
Startup 中:services.Configure(Configuration.GetSection("JWTSetting"));
然后编写jwt帮助类,分别创建jwttoken和验证jwttokenusing fwt.Models;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace fwt
{
///
/// token 帮助类
///
public static class TokenContext
{
///
/// 创建jwttoken,源码自定义
///
public static string CreateToken(JWTPayLoad payLoad, string secret, JWTHeader header = null)
{
if (header == null)
{
header = new JWTHeader()
{
alg = "HS256",
typ = "JWT"
};
}
//添加jwt可用时间(应该必须要的)
var now = DateTime.UtcNow;
payLoad.nbf = ToUnixEpochDate(now);//可用时间起始
payLoad.exp = ToUnixEpochDate(now.Add(TimeSpan.FromSeconds(3600)));//可用时间结束,其中3600是有效时间,根据实际情况自定义
var encodedHeader = Base64UrlEncoder.Encode(JsonConvert.SerializeObject(header));
var encodedPayload = Base64UrlEncoder.Encode(JsonConvert.SerializeObject(payLoad));
var hs256 = new HMACSHA256(Encoding.ASCII.GetBytes(secret));
var encodedSignature = Base64UrlEncoder.Encode(hs256.ComputeHash(Encoding.UTF8.GetBytes(string.Concat(encodedHeader, ".", encodedPayload))));
var encodedJwt = string.Concat(encodedHeader, ".", encodedPayload, ".", encodedSignature);
return encodedJwt;
}
///
/// 创建jwtToken,采用微软内部方法,默认使用HS256加密,如果需要其他加密方式,请更改源码
/// 返回的结果和CreateToken一样
///
public static string CreateTokenByHandler(Dictionary payLoad, string secret)
{
var now = DateTime.UtcNow;
// Specifically add the jti (random nonce), iat (issued timestamp), and sub (subject/user) claims.
// You can add other claims here, if you want:
var claims = new List();
foreach (var key in payLoad.Keys)
{
var tempClaim = new Claim(key, payLoad[key]?.ToString());
claims.Add(tempClaim);
}
// Create the JWT and write it to a string
var jwt = new JwtSecurityToken(
issuer: null,
audience: null,
claims: claims,
notBefore: now,
expires: now.Add(TimeSpan.FromSeconds(3600)),
signingCredentials: new SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secret)), SecurityAlgorithms.HmacSha256));
var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);
return encodedJwt;
}
///
/// 验证身份 验证签名的有效性,
///
///
/// 自定义各类验证; 是否包含那种申明,或者申明的值,
/// 例如:payLoad["aud"]?.ToString() == "roberAuddience";
/// 例如:验证是否过期 等
public static bool Validate(string encodeJwt, Func, bool> validatePayLoad,string secret)
{
var success = true;
var jwtArr = encodeJwt.Split('.');
var header = JsonConvert.DeserializeObject>(Base64UrlEncoder.Decode(jwtArr[0]));
var payLoad = JsonConvert.DeserializeObject>(Base64UrlEncoder.Decode(jwtArr[1]));
var hs256 = new HMACSHA256(Encoding.ASCII.GetBytes(secret));
//首先验证签名是否正确(必须的)
success = success && string.Equals(jwtArr[2], Base64UrlEncoder.Encode(hs256.ComputeHash(Encoding.UTF8.GetBytes(string.Concat(jwtArr[0], ".", jwtArr[1])))));
if (!success)
{
return success;//签名不正确直接返回
}
//其次验证是否在有效期内(也应该必须)
var now = ToUnixEpochDate(DateTime.UtcNow);
success = success && (now >= long.Parse(payLoad["nbf"].ToString()) && now
//再其次 进行自定义的验证
success = success && validatePayLoad(payLoad);
return success;
}
///
/// 获取jwt中的payLoad
///
///
///
public static Dictionary GetPayLoad(string encodeJwt)
{
var jwtArr = encodeJwt.Split('.');
var payLoad = JsonConvert.DeserializeObject>(Base64UrlEncoder.Decode(jwtArr[1]));
return payLoad;
}
public static long ToUnixEpochDate(DateTime date) =>
(long)Math.Round((date.ToUniversalTime() - new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero)).TotalSeconds);
}
}
控制器调用using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using fwt.Models;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using System.Text;
using System.Security.Cryptography;
using Microsoft.Extensions.Options;
namespace fwt.Controllers
{
public class HomeController : Controller
{
private readonly JWTTokenModel _jWTTokenModel;
//依赖注入
public HomeController(IOptions jWTTokenModel)
{
_jWTTokenModel = jWTTokenModel.Value;
}
public IActionResult Index()
{
//获取token
string tokenstr = TokenContext.CreateToken(_jWTTokenModel.payLoad, _jWTTokenModel.secret, _jWTTokenModel.header);
//自定义验证
Func, bool> func = delegate (Dictionary s)
{
if (s["iss"].ToString() == _jWTTokenModel.payLoad.iss
&& s["aud"].ToString() == _jWTTokenModel.payLoad.aud
&& s["sub"].ToString() == _jWTTokenModel.payLoad.sub)
{
return true;
}
return false;
};
//验证token
bool success = TokenContext.Validate(tokenstr, func, _jWTTokenModel.secret);
return View();
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}
ok,原理差不多就是这个样子。官网中也提供了解码的调试器,可以解码生成的token
将生成的token复制到左边即可。
使用场景:比如webapi接口的token验证,就可以用到jwt,先获取登录后的token,把token传入authorization中才能进行下面接口的调用。
总结一哈:由于JSON比XML更简洁,因此在编码时它的大小也更小,使得JWT比SAML更紧凑。这使得JWT成为在HTML和HTTP环境中传递的不错选择。
JSON解析器在大多数编程语言中很常见,因为它们直接映射到对象。相反,XML没有自然的文档到对象映射。这使得使用JWT比使用SAML断言更容易。
个人理解:jwt其实是一种规范,一种加密验证的解决方案,更多的其实是给一个思路,一个标准,不一定要完全按照jwt的格式去加密。一定程度上
可以取代session和cookie进行用户认证,两者各有优缺点。
jwttoken解码_使用 JSON WEB TOKEN (jwt) 验证相关推荐
- php jwt token 解析,JSON Web Token(JWT)入坑详解
JSON Web Token(JWT)入坑详解 龙行 PHP 2019-6-17 1651 0评论 /** JWT生成类 **/ class Jwt { private $al ...
- JSON Web Token (JWT),服务端信息传输安全解决方案
转载自 JSON Web Token (JWT),服务端信息传输安全解决方案 JWT介绍 JSON Web Token(JWT)是一种开放标准(RFC 7519),它定义了一种紧凑独立的基于JSON对 ...
- Json web token (JWT) golang实现
Json web token (JWT) eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG ...
- JSON Web Token (JWT)生成Token及解密实战
转载自 JSON Web Token (JWT)生成Token及解密实战 昨天讲解了JWT的介绍.应用场景.优点及注意事项等,今天来个JWT具体的使用实践吧. 从JWT官网支持的类库来看,jjwt是J ...
- (json web token)JWT攻击
前记 最近国赛+校赛遇到两次json web token的题,发现自己做的并不算顺畅,于是有了这篇学习文章. 为什么要使用Json Web Token Json Web Token简称jwt 顾名思义 ...
- JSON Web Token (JWT)笔记(token实现单点登录功能)
文章目录 前情提要 cookie(储存在用户本地终端上的数据) Cookie特点: session(web服务端内存) cookie和session 单点登录(只登录一次,可使用账号下全部服务)三种方 ...
- JSON Web Token(JWT)对比Opaque Token
身份验证通常用来验证某人或某事是否如它所说的那样是谁或者是什么. 身份验证技术通过测试查看用户的凭据是否与经过身份验证的用户数据库或服务器中的凭据相匹配,从而提供设备访问控制. 基于token的身份验 ...
- 用户登入身份验证,手机app登入身份验证,TokenAuth身份验证,JSON Web Token(JWT)身份验证
JJWT身份验证 1.pom依赖: <dependency ...
- python token认证_理解JWT(JSON Web Token)认证及python实践
最近想做个小程序,需要用到授权认证流程.以前项目都是用的 OAuth2 认证,但是Sanic 使用OAuth2 不太方便,就想试一下 JWT 的认证方式. 这一篇主要内容是 JWT 的认证原理,以及p ...
最新文章
- win7/8SVN必备的4个服务
- mysql报错注入原理,MySQL报错注入
- Dijkstra 贪心算法 动态规划
- The only supported ciphers are AES-128-CBC and AES-256-CBC
- 计算机组成原理 — ARM 体系结构
- 算法提高课-图论-单源最短路的综合应用-AcWing 1135. 新年好:dijkstra和dfs暴搜结合
- 利用FluidMoveBehavior制作出手机通讯录平滑的效果
- Vivado2015.4使用教程(一个完成工程的建立)
- 她说程序员不懂浪漫,生日宴上惨变单身狗,其实,程序员的浪漫你不懂!
- LeetCode——LCP 06.拿硬币
- java线程中Exchanger使用
- 微信公众平台的设计与开发之道
- 《Intriguing properties of neural networks》代码实现——Pytorch
- LA4043 KM算法
- 网管日记:故障网络交换机快速替换方法
- 深度CTR之AFM:基于Attention网络的FM模型
- 分布式任务调度平台XXL-JOB深度实战
- android AMS学习(一)
- opencv实现图片的素描化
- c 链表排序 - 选择排序
热门文章
- 如何用命令将本地项目上传到git
- 环境变量方式使用 Secret - 每天5分钟玩转 Docker 容器技术(158)
- 【spring基础】spring 官方下载地址
- 从封装函数到实现简易版自用jQuery (一)
- 常见CSS两栏式布局
- 《C语言程序设计:问题与求解方法》——3.9节常见编程错误
- 微信支付报错:app没有获取微信支付权限
- 《循序渐进学Spark》一3.5 容错机制及依赖
- 润乾报表实现组内排序报表及改进
- HTML5圆形线性渐变,css中linear-gradient()函数是干什么的?实现线性渐变的圆形边框(代码)...