今天我们来聊一聊关于JWT授权的事情。
JWT:Json Web Token。顾名思义,它是一种在Web中,使用Json来进行Token授权的方案。
既然没有找好密码,token是如何解决信任问题的呢?
解决信任问题,只需要解决两个问题即可:
token是不是来自我信任的机构颁发
token中的信息是否被篡改
对于第一个问题而言,确认token确实是由被信任的第三方颁发的,一般都是通过加密算法来建立信任,颁发时使用密钥进行加密,如果能够对加密内容进行正常解密说明token来自信任方。常用的加密算法分为:
对称可逆加密:使用同一个秘钥来加密解密,如果token能解密就能证明来源,秘钥不对外公开
非对称可逆加密:使用一组秘钥对(私钥加密+公钥解密),如果token能使用公钥进行解密就能证明来源,公钥与私钥之间互相不可推算
优缺点:
对称可逆加密效率高,速度快,但是由于对称可逆加密使用的是同一个秘钥,所以必须向解密的应用提供秘钥,相对而言不安全,所以一般只用于内部应用之间。
非对称可逆加密速度相对慢一些,但是加密时通过私钥加密而解密时只需要提供公钥即可,所以用于对外提供加密机制更加安全可靠,所以多用于向第三方提供加密服务时使用。
算法举例:
HS256
HS256 (带有 SHA-256 的 HMAC 是一种对称算法, 双方之间仅共享一个 密钥。由于使用相同的密钥生成签名和验证签名, 因此必须注意确保密钥不被泄密。
2 RS256
RS256 (采用SHA-256 的 RSA 签名) 是一种非对称算法, 它使用公共/私钥对: 标识提供方采用私钥生成签名, JWT 的使用方获取公钥以验证签名。由于公钥 (与私钥相比) 不需要保护, 因此大多数标识提供方使其易于使用方获取和使用 (通常通过一个元数据URL)。
JWT格式说明
| JWT令牌格式 | 作用 | |
| Header | 头 | { "alg": "HS256", "typ": "JWT"} |
| Payload | 有效载荷 | 使用base64进行序列化,任何人都可以读到,所以不要包含敏感信息 |
| Signature | 签名 |
防止抵赖-防止篡改,一旦头和有效载荷有内容被篡改,则生成签名部分必将与原内容不同 =HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret) |
JWT如何解决信任问题的呢?
将签名部分使用秘钥进行解密,如果可以正常解开,说明令牌来自信任方颁发,将解密后的内容与JWT的头部和有效载荷的base64编码内容对比是否一致,如果一致,说明令牌未被篡改。也就解决了token信任的第二个问题。
算法实现:
下面是使用上述的两种加密算法生成的jwt
HS256算法实现
1 public string GetToken(UserInfoDTO userInfo)
2 {
3 string secretKey = _configuration["SercetKey"];
4 var signingCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey)), SecurityAlgorithms.HmacSha256);
5
6 var claims = new Claim[] {
7 new Claim("id",userInfo.Id.ToString()),
8 new Claim("age",userInfo.Age.ToString()),
9 new Claim("name",userInfo.Name),
10 new Claim("mobile",userInfo.Mobile),
11 new Claim("email",userInfo.EMail),
12 new Claim("role",userInfo.Role),
13 };
14
15 var token = new JwtSecurityToken(
16 issuer: _configuration["Issuer"], //发行人
17 audience: _configuration["Audience"], //受众人
18 claims: claims,
19 expires: DateTime.UtcNow.AddMinutes(2),//60分钟有效期
20 notBefore: DateTime.UtcNow.AddMinutes(1),//1分钟后有效
21 signingCredentials: signingCredentials);
22 string returnToken = new JwtSecurityTokenHandler().WriteToken(token);
23 return returnToken;
24 }
RSA256算法实现
1 public string GetToken(UserInfoDTO userInfo)
2 {
3 string filepath = Directory.GetCurrentDirectory();
4 RSAParameters rSAParameter = default(RSAParameters);
5 //没有生成过私钥文件,就创建,否则读取私钥
6 if (!File.Exists(Path.Combine(filepath, "key.private.json")))
7 {
8 rSAParameter = GenerateAndSaveKey(filepath);
9 }
10 else
11 {
12 rSAParameter = JsonConvert.DeserializeObject<RSAParameters>(File.ReadAllText(Path.Combine(filepath, "key.private.json")));
13 }
14
15 var signingCredentials = new SigningCredentials(new RsaSecurityKey(rSAParameter), SecurityAlgorithms.RsaSha256);
16 var claims = new Claim[] {
17 new Claim("id",userInfo.Id.ToString()),
18 new Claim("age",userInfo.Age.ToString()),
19 new Claim("name",userInfo.Name),
20 new Claim("mobile",userInfo.Mobile),
21 new Claim("email",userInfo.EMail),
22 new Claim("role",userInfo.Role),
23 };
24
25 var token = new JwtSecurityToken(
26 issuer: _configuration["Issuer"], //发行人
27 audience: _configuration["Audience"], //受众人
28 claims: claims,
29 expires: DateTime.UtcNow.AddMinutes(60),//60分钟有效期
30 notBefore: DateTime.UtcNow.AddMinutes(1),//1分钟后有效
31 signingCredentials: signingCredentials);
32 string returnToken = new JwtSecurityTokenHandler().WriteToken(token);
33 return returnToken;
34 }
在postman中请求:

将返回的jwt拿到jwt官网解析即可看到已经包含了我们需要传递的内容。因为jwt中传递的内容可以被看到,所以一定不要传递类似密码这类敏感信息

创建一个webapi项目,作为受保护的资源,开启权限认证,并使用jwt作为鉴权方式
1 services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
2 .AddJwtBearer(configureOptions =>
3 {
4 configureOptions.TokenValidationParameters = new TokenValidationParameters
5 {
6 ValidAudience = Configuration["Audience"],
7 ValidateAudience = true,
8 ValidIssuer = Configuration["Issuer"],
9 ValidateIssuer = true,
10 ValidateLifetime = false,
11 LifetimeValidator = (notBefore, expires, securityToken, validationParameters) => {
12 DateTime now = DateTime.UtcNow;
13 if (now.CompareTo(notBefore) < 0 || now.CompareTo(expires) > 0)
14 return false;
15 return true;
16 },
17 IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["SercetKey"])), //对称加密方式,获取密钥
18 //IssuerSigningKey = new RsaSecurityKey(GetPulicKey()), //非对称加密方式,获取第三方提供的公钥
19 ValidateIssuerSigningKey = true,
20
21 };
22 });
不传递token请求受保护的api,则会返回401

加上获取的token,则可以正常请求

项目源码链接: https://pan.baidu.com/s/1u9Lu7rLq7swSXOdV_sNh-g?pwd=mxfg
似乎无法为此找到有效的答案。我正在阅读Rails教程的第10章第10.1.2节,但似乎无法使邮件程序预览正常工作。我发现处理错误的所有答案都与教程的不同部分相关,我假设我犯的错误正盯着我的脸。我已经完成并将教程中的代码复制/粘贴到相关文件中,但到目前为止,我还看不出我输入的内容与教程中的内容有什么区别。到目前为止,建议是在函数定义中添加或删除参数user,但这并没有解决问题。触发错误的url是http://localhost:3000/rails/mailers/user_mailer/account_activation.http://localhost:3000/rails/mai
rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送
最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总
Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图
关闭。这个问题不符合StackOverflowguidelines.它目前不接受答案。我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。关闭3年前。Improvethisquestion我正处于学习Ruby的阶段,我想查看一些小型库的源代码以了解它们是如何构建的。我不知道什么是小型图书馆,但希望SO能推荐一些易于理解的图书馆来学习。因此,如果有人知道一两个非常小的库,这是新手Rubyists学习的好例子,请推荐!我想使用Manveru'sInnatelib,因为它试图保持在2000LOC以下,但我还不熟悉其中经常使用的Ruby速记。也许大约100-5
我试图在我的网站上实现使用Facebook登录功能,但在尝试从Facebook取回访问token时遇到障碍。这是我的代码:ifparams[:error_reason]=="user_denied"thenflash[:error]="TologinwithFacebook,youmustclick'Allow'toletthesiteaccessyourinformation"redirect_to:loginelsifparams[:code]thentoken_uri=URI.parse("https://graph.facebook.com/oauth/access_token
由于匿名block和散列block看起来大致相同。我正在玩它。我做了一些严肃的观察,如下所示:{}.class#=>Hash好的,这很酷。空block被视为Hash。print{}.class#=>NilClassputs{}.class#=>NilClass为什么上面的代码和NilClass一样,下面的代码又显示了Hash?puts({}.class)#Hash#=>nilprint({}.class)#Hash=>nil谁能帮我理解上面发生了什么?我完全不同意@Lindydancer的观点你如何解释下面几行:print{}.class#NilClassprint[].class#A
我正在尝试创建密码规则来设计可恢复的密码更改。我通过passwords_controller.rb做了一个父类(superclass),但我需要在应用规则之前检查用户角色,但我所拥有的只是reset_password_token。 最佳答案 假设您的模型是用户:User.with_reset_password_token(your_token_here)Source 关于ruby-on-rails-设计通过reset_password_token获取用户,我们在StackOverflow
简单代码require'net/http'url=URI.parse('getjson/otherdatahere[link]')req=Net::HTTP::Get.new(url.to_s)res=Net::HTTP.start(url.host,url.port){|http|http.request(req)}putsres.body只是想知道如何在phpcURL中放置身份验证token,我是这样做的 curl_setopt($ch,CURLOPT_HTTPHEADER,array('Authorization:Bearerxxx'));//Bearertokenfora
我很难理解Ruby中sender和receiver的实际含义。它们一般是什么意思?到目前为止,我只是将它们理解为方法调用和获取其返回值的调用。但是,我知道我的理解还远远不够。谁能给我一个Ruby中发送者和接收者的具体解释? 最佳答案 面向对象中的一个核心概念是消息传递和早期概念化,这在很大程度上借鉴了计算的Actor模型。艾伦·凯(AlanKay)创造了面向对象一词并发明了最早的OO语言之一SmallTalk,他拥有voicedregretatusingatermwhichputthefocusonobjectsinsteadofo