Backend generates public and private keys
Use the RSA.ToXmlString(Boolean) method to generate public and private keys.
RSACryptoServiceProvider rSA = new(); string pubKey = rSA.ToXmlString(false);//Public key string priKey = rSA.ToXmlString(true);//Private key
The backend sends the generated public key to the frontend
Create a get request and send the public key generated by the back-end to the front-end. Please note that the public key generated here is in XML format and needs to be converted to pkcs8 format. The front-end JS can only process the pkcs8 format, and the private key cannot be sent to the front-end! ! ! !
Here you need to install a package XC.RSAUtil for format conversion.
Install-Package XC.RSAUtil -Version 1.3.6
[HttpGet] public object Edd() { var keyList = RsaKeyConvert.PublicKeyXmlToPem(pubKey);//Convert xml format to Pkcs8 return keyList; }
The front end uses the public key to encrypt the password
The encryption library used is the JSEncrypt library. Install the JSEncrypt library.
npm install jsencrypt -D
Page reference
import {JSEncrypt} from 'jsencrypt'
interface
<div id="JWT"> <div> Account: <input type="text" v-model="MyName"/> </div> <div> Password: <input type="text" v-model="MyPassword"/> </div> <button @click="Myinput">Login</button> </div>
Save the account password and the public key sent by the backend.
data() { return { MyName: null,//account MyPassword: null,//Password pubKey:null, //Public key JWTkey:null//JWT token } }
When using the login interface, call the function to receive the public key and save it.
created() { PostJwtEdd().then(res=>{ this.pubKey=res }).catch(err => { console.log(err) }) }
After entering the account password, the front end encrypts the password and sends the encrypted password request to the back end. After the comparison is successful, the front end saves the JWT token.
methods:{ Myinput(){ var encryptor = new JSEncrypt() encryptor.setPublicKey(this.pubKey) var rsaPassWord = encryptor.encrypt(this.MyPassword)//Encrypted password PostJwtDdd(this.MyName, rsaPassWord).then(res => { this.JWTkey=res//Save the JWT token generated by the backend }).catch(err => { console.log(err) }) } }
Send the password part of the axio request
export function PostJwtDdd(MyName,MyPassword){ return request({ method: 'post', url: '/JWTS/Ddd', data:{ MyName, MyPassword } }) }
This is the account number and password ciphertext sent.
Comparison of backend receiving parameters
The backend receives the parameters and decrypts the password ciphertext.
Create a class to receive the account number and encrypted ciphertext.
public class RsaKey { public string MyName { get; set; } public string MyPassword { get; set; } }
Receive the parameters to start decryption and compare the account password.
[HttpPost] public object Ddd([FromBody] RsaKey rsaKey) { rsa.FromXmlString(priKey);//Pass in the private key for decryption byte[] cipherbytex; cipherbytex = rsa.Decrypt(Convert.FromBase64String(rsaKey.MyPassword), false); var c = Encoding.UTF8.GetString(cipherbytex);//Convert to string type MyDbContext md = new MyDbContext();//Create an entity class for the database table var user = md.MyIntroductions.Where(x => x.MyName == rsaKey.MyName).Select(x => x.MyPassword);//Find the password corresponding to the account in the database string users = null; foreach (var v in user) { users = v; } if (user == null) { return new { err = "Account error" }; } else { if (users == c) { //login successful } else { return new { err = "Wrong password" }; } } }
Generate JWT token
After the login is successful, the JWT token is generated and returned to the front end, where it is generated when the login is successful.
Two packages need to be installed.
Package 1: System.IdentityModel.Tokens.Jwt
Install-Package System.IdentityModel.Tokens.Jwt
Package 2: Microsoft.AspNetCore.Authentication.JwtBearer
Install-Package Microsoft.AspNetCore.Authentication.JwtBearer
List<Claim> claims = new List<Claim>(); claims.Add(new Claim("MyName", rsaKey.MyName)); claims.Add(new Claim(ClaimTypes.Role, rsaKey.MyName));//Issue administrator role string key = jwtSettingsOpt.Value.SecKey; DateTime expire = DateTime.Now.AddSeconds(jwtSettingsOpt.Value.ExpireSeconds); byte[] secBytes = Encoding.UTF8.GetBytes(key); var seckey = new SymmetricSecurityKey(secBytes); var credentials = new SigningCredentials(seckey, SecurityAlgorithms.HmacSha256Signature); var tokenDescriptor = new JwtSecurityToken(claims: claims, expires: expire, signingCredentials: credentials); string jwt = new JwtSecurityTokenHandler().WriteToken(tokenDescriptor); return jwt;
This is the JWT token received by the frontend
Backend permission access
The backend creates a post request with [Authorize]
[Authorize] is used to handle permissions. Its function here is to return a 401 error for requests without JWT tokens. That is, we can use this to open some permissions to logged-in users. If there is no JWT token, then Unable to request data.
The post request will return the requester’s account.
[Authorize] [HttpPost] public object Bdd() { return this.User.FindFirst("MyName")!.Value; }
Front-end access with JWT token
It should be noted that the JWT token is sent through a request header of ‘Authorization’, and the format must be:
Authorization: Bearer + a space + JWT token generated by the backend
Front-end interface
<button @click="MyJwt">View permissions</button>
MyJwt(){ var JwtKey='Bearer ' + this.JWTkey console.log(JwtKey) PostJwtBdd(JwtKey).then(res=>{ console.log(res) }).catch(err=>{ console.log(err) }) }
axios request part
export function PostJwtBdd(JwtKey){ return request({ method: 'post', url: '/JWTS/Cdd', headers: { 'Authorization': JwtKey } }) }
After [Authorize(Roles =”admin”)] is configured in the backend request, only users specified in Roles can access its interface. It can generally be used to access administrators. When generating a JWT token when,
Use claims.Add(new Claim(ClaimTypes.Role, ‘user’)); to match, administrator user.
This post request can only be requested by users who are admin.
[Authorize(Roles ="admin")]//Configure that only administrator roles can request [HttpPost] public object Cdd() { return this.User.FindFirst("MyName")!.Value; }
Front-end interface
<button @click="OneJwt">Administrator permissions</button>
OneJwt(){ var JwtKey='Bearer ' + this.JWTkey console.log(JwtKey) PostJwtCdd(JwtKey).then(res=>{ console.log(res) }).catch(err=>{ console.log(err) }) }
In the axios request part, the same request can only be sent through the ‘Authorization’: request header.
Authorization + “space” + generated JWT token
export function PostJwtCdd(JwtKey){ return request({ method: 'post', url: '/JWTS/Cdd', headers: { 'Authorization': JwtKey } }) }
If the wrong JWT token is included, the backend will return a 401 error, as shown in the figure:
And no objects will be returned.