ASP.NET Core 3.1 WebApi+JWT+Swagger+EntityFrameworkCore构建REST API

ASP.NET Core 3.1 WebApi+JWT+Swagger+EntityFrameworkCore构建REST API,第1张

概述一、准备 使用vs2019新建ASP.NET Core Web应用程序,选用api模板: 安装相关的NuGet包: 二、编码 首先编写数据库模型: 用户表 User.cs: 数据库上下文 DemoCo 一、准备使用vs2019新建ASP.NET Core Web应用程序,选用API模板:

安装相关的NuGet包:

二、编码首先编写数据库模型:


用户表 User.cs:
public class User    {        [Key]        public GuID ID { get; set; }        [required]        [Column(Typename = "VARCHAR(16)")]        public string Username { get; set; }        [required]        [Column(Typename = "VARCHAR(16)")]        public string Password { get; set; }    }

数据库上下文 DemoContext.cs,在数据库创建时增加一条种子数据admin:

public class DemoContext : DbContext    {        public DemoContext(DbContextoptions<DemoContext> options)            : base(options)        {        }        public DbSet<User> Users { get; set; }        protected overrIDe voID OnModelCreating(ModelBuilder modelBuilder)        {            base.OnModelCreating(modelBuilder);            modelBuilder.Entity<User>().HasData(new User            {                ID = GuID.Parse("94430DDF-E6E1-4836-A7D2-49A9FCEF722E"),Username = "admin",Password = "123456"            });        }    }
编写数据访问服务:


IUserService接口,这里简单定义几个添加查询的方法:
public interface IUserService    {        Task<IEnumerable<User>> GetUserAsync();        Task<User> GetUserAsync(GuID ID);        Task<User> GetUserAsync(string username,string password);        Task<User> AddUserAsync(string username,string password);    }

UserService实现类:

public class UserService : IUserService    {        private Readonly DemoContext context;        public UserService(DemoContext context)        {            this.context = context ?? throw new ArgumentNullException(nameof(context));        }        public async Task<User> AddUserAsync(string username,string password)        {            User user = new User();            user.ID = GuID.NewGuID();            user.Username = username;            user.Password = password;            await context.Users.AddAsync(user);            context.SaveChanges();            return user;        }        public async Task<User> GetUserAsync(string username,string password)        {            return await context.Users.FirstOrDefaultAsync(p => p.Username == username && p.Password == password);        }        public async Task<IEnumerable<User>> GetUserAsync()        {            return await context.Users.ToListAsync();        }        public async Task<User> GetUserAsync(GuID ID)        {            return await context.Users.FirstOrDefaultAsync(p => p.ID == ID);        }    }
appsettings.Json中增加jwt,efcore相关的配置 JwtSetting、ConnectionStrings:
{  "Logging": {    "LogLevel": {      "Default": "information","Microsoft": "Warning","Microsoft.Hosting.lifetime": "information"    }  },"AllowedHosts": "*","JwtSetting": {    "SecurityKey": "88d082e6-5672-4c6c-bc42-6fcce20fbf51",// 密钥    "Issuer": "jwtIssuertest",// 颁发者    "AudIEnce": "jwtAudIEncetest",// 接收者    "ExpireSeconds": 3600 // 过期时间(3600)  },"ConnectionStrings": {    "DemoContext": "data source=.;Initial Catalog=WebAPIDemoDB;User ID=sa;Password=123456;MultipleActiveResultSets=True;App=EntityFramework"  }}
增加jwt配置对象:

    /// <summary>    /// jwt配置对象    /// </summary>    public class JwtSetting    {        public string SecurityKey { get; set; }        public string Issuer { get; set; }        public string AudIEnce { get; set; }        public int ExpireSeconds { get; set; }    }
public static class AppSettings    {        public static JwtSetting JwtSetting { get; set; }        /// <summary>        /// 初始化jwt配置        /// </summary>        /// <param name="configuration"></param>        public static voID Init(IConfiguration configuration)        {            JwtSetting = new JwtSetting();            configuration.Bind("JwtSetting",JwtSetting);        }    }
在Startup.cs中配置相关服务和中间件:
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)        {            AppSettings.Init(Configuration);            services.AddSwaggerGen(c =>            {                c.SwaggerDoc("v1",new OpenAPIInfo { Title = "My API",Version = "v1" });                // Set the comments path for the Swagger JsON and UI.                var xmlfile = $"{Assembly.GetExecutingAssembly().Getname().name}.xml";                var xmlPath = Path.Combine(AppContext.BaseDirectory,xmlfile);                c.IncludeXmlComments(xmlPath);                c.AddSecurityDeFinition("Bearer",new OpenAPISecurityScheme()                {                    Description = "在下框中输入请求头中需要添加Jwt授权Token:Bearer Token",name = "Authorization",In = ParameterLocation.header,Type = SecuritySchemeType.APIKey,BearerFormat = "JWT",Scheme = "Bearer"                });                c.AddSecurityRequirement(new OpenAPISecurityRequirement                    {                        {                            new OpenAPISecurityScheme{                                Reference = new OpenAPIReference {                                            Type = ReferenceType.SecurityScheme,ID = "Bearer"}                           },new string[] { }                        }                    });            });            services              .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)              .AddJwtBearer(options =>              {                  options.TokenValIDationParameters = new TokenValIDationParameters                  {                      Validissuer = AppSettings.JwtSetting.Issuer,ValIDAudIEnce = AppSettings.JwtSetting.AudIEnce,IssuerSigningKey = new SymmetricSecurityKey(EnCoding.UTF8.GetBytes(AppSettings.JwtSetting.SecurityKey)),// 默认允许 300s  的时间偏移量,设置为0                      ClockSkew = TimeSpan.Zero,};              });            services.AddCors(options =>            {                options.AddPolicy("any",builder =>                    {                        builder.AllowAnyMethod()                            .AllowAnyOrigin()                            .AllowAnyheader();                    });            });            services.AddControllers();            services.AddScoped<IUserService,UserService>();            services.AddDbContext<DemoContext>(opt => opt.UsesqlServer(Configuration.GetConnectionString("DemoContext")));        }        // This method gets called by the runtime. Use this method to configure the http request pipeline.        public voID Configure(IApplicationBuilder app,IWebHostEnvironment env)        {            app.UseAuthentication();            if (env.IsDevelopment())            {                app.UseDeveloperExceptionPage();            }            app.UseSwagger();            app.UseSwaggerUI(c =>            {                c.SwaggerEndpoint("/swagger/v1/swagger.Json","My API V1");            });            app.UseRouting();            app.UseAuthorization();            //CORS 中间件必须配置为在对 UseRouting 和 UseEndpoints的调用之间执行。 配置不正确将导致中间件停止正常运行。            app.UseCors("any");            app.UseEndpoints(endpoints =>            {                endpoints.MapControllers();            });        }    }
打开项目文件,增加项目xml文档生成配置,swagger需要用到:
<Generatedocumentationfile>true</Generatedocumentationfile><Nowarn>$(Nowarn);1591</Nowarn>

数据库迁移:
打开程序包管理控制台:执行命令Add-Migration Initial


然后执行Update-Database


此时数据库已经成功生成:

下面是controller:


先建一个数据传输实体,方便统一controller的返回值:
public class BaseDto<T>    {        public BaseDto(StatusCode code,string message)        {            Code = code;            Message = message;        }        public BaseDto(StatusCode code,string message,T data)        {            Code = code;            Message = message;            Data = data;        }        public StatusCode Code { get; set; }        public string Message { get; set; }        public T Data { get; set; }    }    public enum StatusCode    {        Success = 0,Error = 1,}

UserController:

/// <summary>    /// 用户    /// </summary>    [Authorize]    [Route("API/[controller]")]    [APIController]    public class UserController : ControllerBase    {        private Readonly IUserService userService;        public UserController(IUserService userService)        {            this.userService = userService;        }        /// <summary>        /// 所有用户        /// </summary>        /// <returns></returns>        [Route("")]        [httpGet]        public async Task<ActionResult<BaseDto<IEnumerable<User>>>> Get()        {            var users = await userService.GetUserAsync();            BaseDto<IEnumerable<User>> dto = new BaseDto<IEnumerable<User>>(Dto.StatusCode.Success,"",users);            return Ok(dto);        }        /// <summary>        /// 当前用户        /// </summary>        /// <returns></returns>        [Route("me")]        [httpGet]        public async Task<ActionResult<BaseDto<User>>> UserInfo()        {            string ID = User.FindFirst("ID")?.Value;            var user = await userService.GetUserAsync(GuID.Parse(ID));            BaseDto<User> dto = new BaseDto<User>(Dto.StatusCode.Success,user);            return Ok(dto);        }        /// <summary>        /// 根据ID获取用户        /// </summary>        /// <param name="ID"></param>        /// <returns></returns>        [Route("{ID}")]        [httpGet]        public async Task<ActionResult<BaseDto<User>>> Get(GuID ID)        {            var user = await userService.GetUserAsync(ID);            BaseDto<User> dto = new BaseDto<User>(Dto.StatusCode.Success,user);            return Ok(dto);        }        /// <summary>        /// 添加用户        /// </summary>        /// <param name="loginParameter"></param>        /// <returns></returns>        [httpPost]        public async Task<ActionResult<BaseDto<User>>> Add(LoginParameter loginParameter)        {            var user = await userService.AddUserAsync(loginParameter.Username,loginParameter.Password);            BaseDto<User> dto = new BaseDto<User>(Dto.StatusCode.Success,user);            return Ok(dto);        }    }    public class LoginParameter    {        public string Username { get; set; }        public string Password { get; set; }    }

TokenController:

/// <summary>    /// 鉴权    /// </summary>    [Route("API/[controller]")]    [APIController]    public class TokenController : ControllerBase    {        private Readonly IUserService userService;        public TokenController(IUserService userService)        {            this.userService = userService;        }        /// <summary>        /// 获取token        /// </summary>        /// <param name="loginParameter"></param>        /// <returns></returns>        [AllowAnonymous]        [httpPost(name = nameof(Login))]        public async Task<ActionResult<BaseDto<object>>> Login([FromBody]LoginParameter loginParameter)        {            var user = await userService.GetUserAsync(loginParameter.Username,loginParameter.Password);            if (user != null)            {                var token = AppHelper.Instance.GetToken(user);                BaseDto<object> dto = new BaseDto<object>(Dto.StatusCode.Success,new { token });                return Ok(dto);            }            return Ok(new BaseDto<object>(Dto.StatusCode.Error,null));        }    }

AppHelper中生成token的方法:

public class AppHelper    {        public Readonly static AppHelper Instance = new AppHelper();        private AppHelper() { }        /// <summary>        /// 生成token        /// </summary>        /// <param name="user"></param>        /// <returns></returns>        public string GetToken(User user)        {            //创建用户身份标识,可按需要添加更多信息            var claims = new Claim[]            {                new Claim(JwtRegisteredClaimnames.Jti,GuID.NewGuID().ToString()),new Claim("ID",user.ID.ToString(),ClaimValueTypes.Integer32),// 用户ID                new Claim("name",user.Username),// 用户名            };            var key = new SymmetricSecurityKey(EnCoding.UTF8.GetBytes(AppSettings.JwtSetting.SecurityKey));            var creds = new SigningCredentials(key,SecurityAlgorithms.HmacSha256);            //创建令牌            var token = new JwtSecurityToken(              issuer: AppSettings.JwtSetting.Issuer,audIEnce: AppSettings.JwtSetting.AudIEnce,signingCredentials: creds,claims: claims,notBefore: DateTime.Now,expires: DateTime.Now.AddSeconds(AppSettings.JwtSetting.ExpireSeconds)            );            string jwtToken = new JwtSecurityTokenHandler().Writetoken(token);            return jwtToken;        }    }
三、效果

运行项目,浏览器访问:


测试一下用户接口:


这时返回401错误,因为我们还没有鉴权
使用admin/123456获取token:


拿到token 点击authorize:


然后再测试用户接口:


此时已经可以正常请求。
代码:https://github.com/xiajingren/NetCore3.1-WebApi-Demo

总结

以上是内存溢出为你收集整理的ASP.NET Core 3.1 WebApi+JWT+Swagger+EntityFrameworkCore构建REST API全部内容,希望文章能够帮你解决ASP.NET Core 3.1 WebApi+JWT+Swagger+EntityFrameworkCore构建REST API所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1214896.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存