.NET经销商实战(三)——md5加密,反射注入仓储与服务,及生成token
1.添加DealerPlatform.Common类库项目,这个项目被DealerPlatform.Service所引用
首先在该项目中添加nuget包 Microsoft.AspNetCore.Authentication.JwtBearer
2.添加TokenModule文件夹,这是为了写token的生成帮助类,这个类库结构如下
3.JwtTokenModel代码如下:
点击查看代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace DealerPlatform.Common.JwtTokenModule.Models
{
///
/// jwt模型
///
public class JwtTokenModel
{
///
/// 发行人
///
///
public string Issuer { get; set; }
///
/// 观众
///
///
public string Audience { get; set; }
///
/// 过期时间
///
///
public int Expires { get; set; }
///
/// 安全
///
///
public string Security { get; set; }
public int Id { get; set; }
public string CustomerNo { get; set; }
public string CustomerName { get; set; }
}
}
这个类只是起到映射的作用,为了和appsetting中的jwt键值对匹配,添加一些我们需要的用户信息,比如ID,CustomerNo,CustomerName等信息
4.为了方便我们调用,所以写成了静态类
TokenHelper代码如下:
点击查看代码
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 DealerPlatform.Common.JwtTokenModule.Models;
using Microsoft.IdentityModel.Tokens;
namespace DealerPlatform.Common
{
public static class TokenHelper
{
public static string CreateToken(JwtTokenModel model)
{
var claims = new[]{
new Claim("Id",model.Id.ToString()),
new Claim("CustomerNo",model.CustomerNo),
new Claim("CustomerName",model.CustomerName)
};
//生成密钥
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(model.Security));
//通过HmacSha256算法生成秘钥
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
issuer: model.Issuer,
audience: model.Audience,
expires: DateTime.Now.AddMinutes(model.Expires),
signingCredentials: creds,//秘钥
claims: claims);
//通过我们传入的参数生成token
var accessToken = new JwtSecurityTokenHandler().WriteToken(token);
return accessToken;
}
}
}
具体过程不解释了,都在注释里了,这时,我们已经封装好了token帮助类,留着后面用,
生成token的话,我们先将用户输入的密码加密一下,我们接下来写md5加密扩展类
5.为了方便我们调用,所以写成了扩展类,代码如下,很简单的代码,不解释了
点击查看代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace DealerPlatform.Common.Md5Helper
{
public static class Md5Helper
{
///
/// MD5加密
///
///
public static string ToMd5(this string str)
{
MD5 md5 = new MD5CryptoServiceProvider();
byte[] bytes = md5.ComputeHash(Encoding.Default.GetBytes(str + "@rookie.Wang"));
var md5Str = BitConverter.ToString(bytes).Replace("-", "");
return md5Str;
}
}
}
6.一般情况下,我们不在controller写生成token的方法,一般另外写一个服务用来生成token,我为了偷懒就写在了LoginController中
代码如下:
点击查看代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DealerPlatform.Common;
using DealerPlatform.Common.JwtTokenModule.Models;
using DealerPlatform.Service.CustomerApp;
using DealerPlatform.Service.CustomerApp.Dto;
using Microsoft.AspNetCore.Mvc;
namespace DealerPlatform.Web.Controllers
{
[ApiController]
[Route("[controller]/[action]")]
public class LoginController : Controller
{
public IConfiguration Configuration { get; set; }
public LoginController(ICustomerService customerService, IConfiguration configuration)
{
this.Configuration = configuration;
CustomerService = customerService;
}
public ICustomerService CustomerService { get; }
[HttpPost]
public async Task CheckLogin(CustomerLoginDto dto)
{
var isSuccess = await CustomerService.CheckPassword(dto);
if (isSuccess)
{
var customer = await CustomerService.GetCustomerAsync(dto.CustomerNo);
var token = GetToken(customer.Id, customer.CustomerNo, customer.CustomerName);
return token;
}
return "用户或密码错误!";
}
///
/// 获取token
///
///
///
///
///
private string GetToken(int userId, string customerNo, string customerName)
{
//将appsetting中的配置读取到model中
var tokenModel = Configuration.GetSection("Jwt").Get();
tokenModel.Id = userId;
tokenModel.CustomerNo = customerNo;
tokenModel.CustomerName = customerName;
var token = TokenHelper.CreateToken(tokenModel);
return token;
}
}
}
第二个方法是生成token用的
7.在customer.Pwd类中修改代码如下,添加md5加密
点击查看代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DealerPlatform.Common.Md5Helper;
using DealerPlatform.Core.Repository;
using DealerPlatform.Domain.Models;
using DealerPlatform.Service.CustomerApp.Dto;
namespace DealerPlatform.Service.CustomerApp
{
public partial class CustomerService
{
public async Task CheckPassword(CustomerLoginDto dto)
{
// if (string.IsNullOrWhiteSpace(dto.CustomerNo) || string.IsNullOrWhiteSpace(dto.Password))
// {
// throw new Exception("账号或密码不能为空!");
// }
//判断当前dto中是否为空
var res = CustomerPwdRepo.GetAsync(s => s.CustomerNo == dto.CustomerNo && s.CustomerPwd1 == dto.Password.ToMd5());
if (res != null)
{
return true;
}
else
{
return false;
}
}
}
}
8.这样我们的md5加密与生成token1就做好了,为了方便我们以后的开发,利用反射注入仓储与服务,新增一个项目
DealerPlatform.Extensions,这个项目也是被service项目引用,这个项目引入Microsoft.Extensions.DependencyInjection
包
10.新增ServiceCollectionExtensions类,为了反射注入仓储与服务,差点忘记了,在Domain项目中加入一个接口IocTag,让所有service的接口继承它,为了方便检索程序集,
在DealerPlatform.Core中的Repository文件夹中的泛型接口IRepository,添加一个接口IRepository,让泛型接口IRepository继承IRepository即可
代码如下:
点击查看代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using DealerPlatform.Core.Repository;
using DealerPlatform.Domain;
using Microsoft.Extensions.DependencyInjection;
namespace DealerPlatform.Extensions
{
///
/// 服务注入扩展类
///
public static class ServiceCollectionExtensions
{
public static IServiceCollection RepositoryRegister(this IServiceCollection services)
{
//读取DealerPlatform.Core程序集
var asmCore = Assembly.Load("DealerPlatform.Core");
//获取所有类型
//获取Repository的泛型类"Repository`1"
//反射获取泛型接口有问题
var implementationTypes = asmCore.GetTypes().Where(s => s.IsAssignableTo(typeof(IRepository))
&& !s.IsInterface
&& !s.IsAbstract);
foreach (var implementationType in implementationTypes)
{
services.AddTransient(typeof(IRepository<>), implementationType);
}
// var interfaceType = implementationType?.GetInterface("IRepository`1");
// services.AddTransient(interfaceType, implementationType);
return services;
}
public static IServiceCollection ServiceRegister(this IServiceCollection services)
{
//读取DealerPlatform.Core程序集
var asmService = Assembly.Load("DealerPlatform.Service");
//获取所有类型
//获取Repository的泛型类"Repository`1"
//反射获取泛型接口有问题
var implementationTypes = asmService.GetTypes().Where(s =>
s.IsAssignableTo(typeof(IocTag))
&& !s.IsInterface
&& !s.IsAbstract);
foreach (var implementationType in implementationTypes)
{
var interfaceType = implementationType.GetInterfaces().Where(s => s != typeof(IocTag)).FirstOrDefault();
services.AddTransient(interfaceType, implementationType);
}
return services;
}
}
}
9.修改Program文件如下:
点击查看代码
using DealerPlatform.Core.Repository;
using DealerPlatform.Domain.Models;
using DealerPlatform.Extensions;
using DealerPlatform.Service;
using DealerPlatform.Service.CustomerApp;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
var configuration = builder.Configuration;
builder.Services.AddDbContext(opt =>
opt.UseSqlServer(configuration.GetConnectionString("Default")));
builder.Services.AddAutoMapper(typeof(DealerPlatformProfile));
//反射注册Repository
builder.Services.RepositoryRegister();
builder.Services.ServiceRegister();
// builder.Services.AddTransient(typeof(IRepository<>), typeof(Repository<>));
//builder.Services.AddTransient();
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
这样就可以生成token了,试一下你的登录接口,看看能不能正确生成token,有问题及时向我反馈
下一节开始讲automapper的使用