当前位置:网站首页>How to use JWT for authentication and authorization
How to use JWT for authentication and authorization
2022-07-28 11:34:00 【biyusr】
brief introduction
JWT A compact 、 The self-contained way , Used as a JSON Objects transmit information securely between parties . This information can be verified and trusted , Because it's digitally signed .
Workflow
1、 Users use accounts 、 Password login application , The login request is sent to the authentication server .
2、 The authentication server performs user authentication , Then create JWT String returned to client .
3、 When a client requests an interface , On the request headband JWT. Application server authentication JWT Legitimacy , If it is legal, continue to call the application interface and return the result .
data structure
JWT from 3 Part of it is made up of : header (Header)、 Payload (Payload) And signature (Signature). At the time of transmission , Will JWT Of 3 The parts are carried out separately Base64 Use... After coding . Connect to form the final transmitted string JWT from 3 Part of it is made up of : header (Header)、 Payload (Payload) And signature (Signature). At the time of transmission , Will JWT Of 3 The parts are carried out separately Base64 Use... After coding . Connect to form the final transmitted string JWT It is generally such a string , It's divided into three parts , With "." separate :
xxxxx.yyyyy.zzzzz
JWTString=Base64(Header).Base64(Payload).HMACSHA256(base64UrlEncode(header)+"."+base64UrlEncode(payload),secret)
token Advantages of certification
phase ⽐ On Session The certification ⽅ In other words , send ⽤ jwt Into the ⾏⾝ The certification mainly includes the following ⾯ advantage
1.⽆ state
2. Effectively avoided CSRF attack
3. Suitable for mobile end ⽤
4. Single sign on friendly
NETCore Use JWT
Add data access simulation api,ValuesController
among api/value1 It's directly accessible ,api/value2 Added permission verification feature tag [Authorize]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Demo.Jwt.Controllers
{
[ApiController]
public class ValuesController : ControllerBase
{
[HttpGet]
[Route("api/value1")]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "value1", "value1" };
}
[HttpGet]
[Route("api/value2")]
[Authorize]
public ActionResult<IEnumerable<string>> Get2()
{
return new string[] { "value2", "value2" };
}
}
}
Add simulated Login , Generate Token Of api,AuthController
Let's simulate login verification , Only the user password is verified. If it is not empty, it passes the verification , Perfect the logic of verifying users and passwords in the real environment .
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
namespace Demo.Jwt.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class AuthController : ControllerBase
{
[AllowAnonymous]
[HttpGet]
public IActionResult Get(string userName, string pwd)
{
if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(pwd))
{
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") ,
new Claim (JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddMinutes(30)).ToUnixTimeSeconds()}"),
new Claim(ClaimTypes.Name, userName)
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Const.SecurityKey));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
issuer: Const.Domain,
audience: Const.Domain,
claims: claims,
expires: DateTime.Now.AddMinutes(30),
signingCredentials: creds);
return Ok(new
{
token = new JwtSecurityTokenHandler().WriteToken(token)
});
}
else
{
return BadRequest(new { message = "username or password is incorrect." });
}
}
}
}
Startup add to JWT Verify the relevant configuration of the
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Text;
namespace Demo.Jwt
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// add to jwt verification :
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options => {
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,// Whether the validation Issuer
ValidateAudience = true,// Whether the validation Audience
ValidateLifetime = true,// Is the failure time verified
ClockSkew = TimeSpan.FromSeconds(30),
ValidateIssuerSigningKey = true,// Whether the validation SecurityKey
ValidAudience = Const.Domain,//Audience
ValidIssuer = Const.Domain,//Issuer, These two and the front sign jwt The Settings are consistent
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Const.SecurityKey))// Get SecurityKey
};
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
/// add to jwt verification
app.UseAuthentication();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}
namespace Demo.Jwt
{
public class Const
{
/// <summary>
/// Here's a demonstration , Write a key . The actual production environment can be read from the configuration file , This is a key randomly generated by online tools
/// </summary>
public const string SecurityKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDI2a2EJ7m872v0afyoSDJT2o1+SitIeJSWtLJU8/Wz2m7gStexajkeD+Lka6DSTy8gt9UwfgVQo6uKjVLG5Ex7PiGOODVqAEghBuS7JzIYU5RvI543nNDAPfnJsas96mSA7L/mD7RTE2drj6hf3oZjJpMPZUQI/B1Qjb5H3K3PNwIDAQAB";
public const string Domain = "http://localhost:5000";
}
}
In actual development, we need to use the following means to increase JWT The security of :
1、 because JWT Is passed in the request header , So in order to avoid network hijacking , Recommended HTTPS To transmit , More secure
2、JWT The key of hash signature is stored in the server , So as long as the server is not broken , Theoretically JWT Is safe . So we need to ensure the security of the server
3、JWT Violent exhaustion can be used to crack , So in order to deal with this cracking method , The hash signature key of the server can be changed regularly ( Equivalent to salt value ). This ensures that when the cracking results come out , Your key has also been changed
token After expired , How to renew automatically
1、 The way 1
take token The expiration time is set to 15 minute ;
The front end initiates a request , Back-end verification token Is it overdue ; If expired , The front end initiates a refresh token request , The back end returns a new... For the front end token;
The front end is new token Initiate request , The request is successful ;
If you want to achieve 72 Hours , You must log in again , The back-end needs to record the login time of each user ; Every time a user requests , Check the last login date of the user , Exceed 72 Hours , Then refuse to refresh token Request , request was aborted , Go to the login page .
In addition, the back-end can also refresh records token The number of times , For example, refresh at most 50 Time , If it reaches 50 Time , Refresh is no longer allowed , User reauthorization required .
2、 The way 2
After successful login , Backend return access_token and refresh_token, The client caches these two types of data token;
Use access_token Request interface resources , Successful call ; If token Overtime , The client carries refresh_token call token Refresh interface to get new data access_token;
The backend accepts the refresh token After request , Check refresh_token Is it overdue . If expired , Refuse to refresh , After the client receives the status , Go to the landing page ; If not expired , Generate a new access_token Return to the client .
The client carries new access_token Call the above resource interface again .
After the client logs out or changes the password , Write off old token, send access_token and refresh_token invalid , At the same time, clear the client access_token and refresh_toke.
The backend implementation token Expired can also be used Redis To store token, Set up redis Expiration time of key value pair . If you find that redis Does not exist in the token The record of , explain token It's overdue .
边栏推荐
- web安全入门-Radius协议应用
- CVPR2020 best paper:对称可变形三维物体的无监督学习
- C language uses double pointer to realize simple factory mode (polymorphism)
- Why does MySQL sometimes choose the wrong index?
- Detailed explanations of%*d,%.*s, etc. of [C language]: "recommended collection"
- 小水滴2.0网站导航网模板
- 1天涨粉81W,打造爆款短视频的秘诀是什么?
- Using C language to compile student achievement management system (C language student achievement management system deleted)
- Cvpr2021 pedestrian re identification /person re identification paper + summary of open source code
- Learn to use MySQL explain to execute the plan, and SQL performance tuning is no longer difficult
猜你喜欢

Learn to use MySQL explain to execute the plan, and SQL performance tuning is no longer difficult

Install SSL Certificate in Litespeed web server

What is WordPress

机器学习强基计划0-5:为什么学习的本质是泛化能力?
![[极客大挑战 2019]BabySQL-1|SQL注入](/img/21/b5b4727178a585e610d743e92248f7.png)
[极客大挑战 2019]BabySQL-1|SQL注入
![Leetcode:1300. the sum of the array closest to the target value after transforming the array [dichotomy]](/img/da/51c4051464d52eae10d93e881cfdf5.png)
Leetcode:1300. the sum of the array closest to the target value after transforming the array [dichotomy]

Byte side: how to realize reliable transmission with UDP?

Why should coding and modulation be carried out before transmission

Encryption defect of icloud Keychain in Apple mobile phone

拥抱开源指南
随机推荐
Blackboard cleaning effect shows H5 source code + very romantic / BGM attached
擦黑板特效表白H5源码+非常浪漫/附BGM
What's the secret of creating a popular short video?
Understand several concepts of Oracle
[FPGA tutorial case 41] image case 1 - reading pictures through Verilog
Flutter tutorial flutter navigator 2.0 with gorouter, use go_ Router package learn about the declarative routing mechanism in fluent (tutorial includes source code)
GIS数据漫谈(五)— 地理坐标系统
What functions does MySQL have? Don't look everywhere. Just look at this.
Byte side: how to realize reliable transmission with UDP?
No swagger, what do I use?
2021-03-24
WinForm generates random verification code
Summary of the second semester of junior year
[MySQL from introduction to proficiency] [advanced chapter] (IX) precautions for InnoDB's b+ tree index
「Node学习笔记」Koa框架学习
Postgres overview
18张图,直观理解神经网络、流形和拓扑
What is the process of switching c read / write files from user mode to kernel mode?
[MySQL from introduction to proficiency] [advanced chapter] (x) MyISAM's indexing scheme & advantages and disadvantages of indexing
[MySQL] MySQL error "error 2006 (HY000): MySQL server has gone away"