承接上篇,这里主要介绍如何实现cookie验证登录以及简单的BaseRepository编写。废话不多说,下面进入主题。
一、cookie验证登录
1、startup的ConfigurationServices方法加上如下代码:
同样startup的Configure方法加上如下代码:
2、继承AuthorizeAttribute标签并实现IAuthorizationFilter接口,代码如下:
using Microsoft.AspNetCore.Authentication;using Microsoft.AspNetCore.Authentication.Cookies;using Microsoft.AspNetCore.Authorization;using Microsoft.AspNetCore.Http;using Microsoft.AspNetCore.Mvc;using Microsoft.AspNetCore.Mvc.Abstractions;using Microsoft.AspNetCore.Mvc.Filters;using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;namespace Ye.BoardMessage.WebApp.Models{ ???/// <summary> ???/// 跳过检查属性 ???/// </summary> ???[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] ???public sealed class SkipUserAuthorizeAttribute : Attribute, IFilterMetadata ???{ ???} ???[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] ???public class UserAuthorizeAttribute : AuthorizeAttribute, IAuthorizationFilter ???{ ???????public UserAuthorizeAttribute() ???????{ ???????????this.AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme; ???????} ???????public virtual void OnAuthorization(AuthorizationFilterContext filterContext) ???????{ ???????????var authenticate = filterContext.HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme); ???????????if (authenticate.Result.Succeeded || this.SkipUserAuthorize(filterContext.ActionDescriptor)) ???????????{ ???????????????return; ???????????} ???????????HttpRequest httpRequest = filterContext.HttpContext.Request; ???????????string url = "/Account/Login"; ???????????url = string.Concat(url, "?returnUrl=", httpRequest.Path); ???????????RedirectResult redirectResult = new RedirectResult(url); ???????????filterContext.Result = redirectResult; ???????????return; ???????} ???????protected virtual bool SkipUserAuthorize(ActionDescriptor actionDescriptor) ???????{ ???????????bool skipAuthorize = actionDescriptor.FilterDescriptors.Where(a => a.Filter is SkipUserAuthorizeAttribute).Any(); ???????????if (skipAuthorize) ???????????{ ???????????????return true; ???????????} ???????????return false; ???????} ???}}
3、验证,代码如下:
[HttpPost] ???????[ValidateAntiForgeryToken] ???????public async Task<IActionResult> Login(string email, string password) ???????{ ???????????password = MD5Encrypted(password); ???????????var serviceResponse = service.Login(email, password); ???????????if (!serviceResponse.IsSuccess) ???????????{ ???????????????return Content("用户名或者密码错误“); ???????????} ???????????var claims = new List<Claim> ???????????????{ ???????????????????new Claim(ClaimTypes.Name, serviceResponse.Result.Email), ???????????????????new Claim("FullName", serviceResponse.Result.FullName), ???????????????????new Claim(ClaimTypes.Role, "Administrator"), ???????????????}; ???????????var claimsIdentity = new ClaimsIdentity( ???????????????claims, CookieAuthenticationDefaults.AuthenticationScheme); ???????????await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, ????????????????new ClaimsPrincipal(claimsIdentity)); ???????????return LocalRedirect(Request.Query["ReturnUrl"].ToString() ?? "/"); ???????}
4、退出,代码如下:
[Models.UserAuthorize] ???????[HttpGet] ???????public async Task<IActionResult> Logout() ???????{ ???????????await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); ???????????return LocalRedirect("/Account/Login"); ???????}
说明:以上代码的实现参考了 《这个大神的博客》
二、BaseRepository实现
封装了基本的增删改查方法,可以与其他仓储共用。此外,有个比较大的缺陷,没有实现事务方面的UnitOfWork,对这个感兴趣的看官可以自行实现,亦可以参考ABP的EF实现,这里有部分代码也是参考ABP的实现的。好了,废话不多说,上代码:
接口:
using Microsoft.EntityFrameworkCore;using Microsoft.EntityFrameworkCore.ChangeTracking;using System;using System.Collections.Generic;using System.Linq;using System.Linq.Expressions;using System.Text;using System.Threading.Tasks;namespace Ye.BoardMessage.Entity.IRepositories{ ???public interface IBaseRepository<TEntity,TKey> where TEntity : class,new() ???{ ???????bool Insert(TEntity entity); ???????Task<EntityEntry<TEntity>> InsertAsync(TEntity entity); ???????TEntity Update(TEntity entity); ???????Task<TEntity> UpdateAsync(TEntity entity); ???????void Delete(TEntity entity); ???????void Delete(IEnumerable<TEntity> entities); ???????TEntity First(); ???????Task<TEntity> FirstAsync(); ???????TEntity First(Expression<Func<TEntity, bool>> where); ???????Task<TEntity> FirstAsync(Expression<Func<TEntity, bool>> where); ???????IQueryable<TEntity> Query(); ???????IQueryable<TEntity> Query(Expression<Func<TEntity,bool>> where); ???????DbContext DbContext { get; } ???????int SaveChanged(); ???}}
实现:
using Microsoft.EntityFrameworkCore;using Microsoft.EntityFrameworkCore.ChangeTracking;using System;using System.Collections.Generic;using System.Linq.Expressions;using System.Text;using System.Threading.Tasks;using Ye.BoardMessage.Entity.IRepositories;using System.Linq;namespace Ye.BoardMessage.Repository{ ???public class BaseRepository<TEntity, TKey> : IBaseRepository<TEntity, TKey> where TEntity : class, new() ???{ ???????private DbContext _context; ???????protected BaseRepository(DbContext context) ???????{ ???????????this._context = context; ???????} ???????public bool Insert(TEntity entity) ???????{ ???????????if (null == entity) ???????????????return false; ???????????Table.Add(entity); ???????????return true; ???????} ???????public Task<EntityEntry<TEntity>> InsertAsync(TEntity entity) ???????{ ???????????return Table.AddAsync(entity); ???????} ???????public TEntity Update(TEntity entity) ???????{ ???????????AttachIfNot(entity); ???????????_context.Entry(entity).State = EntityState.Modified; ???????????return entity; ???????} ???????public Task<TEntity> UpdateAsync(TEntity entity) ???????{ ???????????return Task.FromResult(Update(entity)); ???????} ???????public void Delete(TEntity entity) ???????{ ???????????AttachIfNot(entity); ???????????Table.Remove(entity); ???????} ???????public void Delete(IEnumerable<TEntity> entities) ???????{ ???????????foreach (TEntity item in entities) ???????????????Delete(item); ???????} ???????public TEntity First() ???????{ ???????????return Table.First(); ???????} ???????public Task<TEntity> FirstAsync() ???????{ ???????????return Table.FirstAsync(); ???????} ???????public TEntity First(Expression<Func<TEntity, bool>> where) ???????{ ???????????if (null == where) ???????????????return null; ???????????return Table.First(where); ???????} ???????public Task<TEntity> FirstAsync(Expression<Func<TEntity, bool>> where) ???????{ ???????????if (null == where) ???????????????return null; ???????????return Table.FirstAsync(where); ???????} ???????public DbContext DbContext => _context; ???????public DbSet<TEntity> Table ???????{ ???????????get ???????????{ ???????????????return _context.Set<TEntity>(); ???????????} ???????} ???????public IQueryable<TEntity> Query() ???????{ ???????????return Table.AsQueryable<TEntity>(); ???????} ???????public IQueryable<TEntity> Query(Expression<Func<TEntity, bool>> where) ???????{ ???????????if (null != where) ???????????????return Table.Where(where); ???????????else ???????????????return Query(); ???????} ???????protected virtual void AttachIfNot(TEntity entity) ???????{ ???????????if (!Table.Local.Contains(entity)) ???????????{ ???????????????Table.Attach(entity); ???????????} ???????} ???????public int SaveChanged() ???????{ ???????????return _context.SaveChanges(); ???????} ???}}
三、总结
EFCore的使用与EntityFramework并无多大区别;asp.net core 安全方面集成的东西很多,光是官方文档就占据了上十个篇幅来介绍,在这方面还需要下苦工来研究,可谓 ”路漫漫其修远兮“ 。这里稍微提下,前端模板是使用开源的前端模板《SB-admin》,一款bootstrap风格的模板。下面上几个图片看看效果。
1、登录
2、首页
3、列表页面
至此,这个系列已经基本完毕,下篇将简单介绍下如何安装以及使用(网上参考资料太多,本人主要是整理下本人觉得有用的博文)。
asp.net core2.1+EFCore + MVC开发留言管理项目实战(二)
原文地址:https://www.cnblogs.com/wind-ye/p/9739201.html