[C#][ASP.NET] Web API 开发心得 (4) - 使用 FormsAuthentication 进行 A

今天要介绍在 Web API 使用 表单验证 (FormsAuthentication) 进行授权验证。

常见的验证机制主要分为两类:

Cookie-Based Authentication: 使用浏览器的 Cookie 储存使用者验证资讯,此类验证方式很早就有了,大部分网站的登入机制都是此类。

Token-Based Authentication: 使用 Token 储存使用者验证资讯,Token 为一串加密文字,较 Cookie 灵活,可用于不支援 Cookie 的装置上,这种验证方式较新,主要是近几年 APP 和社群网站兴起,用于 API 的授权和验证。

本篇会介绍第一种方式,Cookie-Based 虽然比较旧,但还是很好用的网站登入机制且较 Token-Based 简单,之后有机会再介绍 Token-Based,我自己也还没实作过,蛮想玩看看的。

下图为网站登入流程图。

http://img2.58codes.com/2024/20106865ncaOHSsfOs.jpg

浏览器送出帐号和密码做登入的动作伺服器登入成功伺服器将加密后带有使用者资讯的 Cookie 写回浏览器浏览器向 API 请求资料并携带认证 Cookie伺服器 Cookie 认证成功伺服器回传浏览器请求的资料

浏览器每次和 API 请求资料,都需要先验证 Cookie 资讯,判断使用者是否具有资料的存取权限。

实作

新增 Identity 列举 (Enum) 管理使用者身分,使用 Enum 的优点 另一篇 文章有详细说明,这里就不再赘述。

public enum Identity{    [Description("管理者")]    Admin = 1,    [Description("一般使用者")]    User = 2,}

新增 User 类别定义要存入 Cookie 的资讯。

public class User{    //流水号    public int Id { get; set; }    //帐号    public string UserId { get; set; }    //名称    public string UserName { get; set; }    //身分    public Identity Identity { get; set; }}

新增 AuthManager 类别管理登入、登出和取得使用者资讯的操作。

public class AuthManager{    //登入    public void SignIn(User user)    {        //新增表单验证用的票证        var ticket = new FormsAuthenticationTicket(1,   //版本            //使用者名称            user.UserName,            //发行时间            DateTime.Now,            //有效期限            DateTime.Now.AddMinutes(60),            //是否将 Cookie 设定成 Session Cookie,如果是则会在浏览器关闭后移除            false,            //将要记录的使用者资讯转换为 JSON 字串            JsonConvert.SerializeObject(user),            //储存 Cookie 的路径            FormsAuthentication.FormsCookiePath);        //将 Ticket 加密        var encTicket = FormsAuthentication.Encrypt(ticket);        //将 Ticket 写入 Cookie        HttpContext.Current.Response.Cookies.Add(            new HttpCookie(FormsAuthentication.FormsCookieName, encTicket));    }    //登出    public void SignOut()    {        //移除浏览器的表单验证        FormsAuthentication.SignOut();    }    //取得使用者资讯    public User GetUser()    {        //取得 ASP.NET 使用者        var user = HttpContext.Current.User;        //是否通过验证        if (user?.Identity?.IsAuthenticated == true)        {            //取得 FormsIdentity            var identity = (FormsIdentity)user.Identity;            //取得 FormsAuthenticationTicket            var ticket = identity.Ticket;            //将 Ticket 内的 UserData 解析回 User 物件            return JsonConvert.DeserializeObject<User>(ticket.UserData);        }        return null;    }}

新增 SignInViewModel 类别接收传回的帐号和密码,ViewModel 的功能是接收前端传回的资料,或回传资料给前端,作为内部和外部沟通的桥樑。

public class SignInViewModel{    //帐号    public string UserId { get; set; }    //密码    public string Password { get; set; }}

新增 AuthController 测试登入和登出相关功能。

[RoutePrefix("api/auth")]public class AuthController : ApiController{    private AuthManager _authManager;    public AuthController()    {        _authManager = new AuthManager();    }    //登入    [HttpPost]    [Route("signIn")]    public void SignIn(SignInViewModel model)    {        //模拟从资料库取得资料        if (!(model.UserId == "abc" && model.Password == "123"))        {            throw new Exception("登入失败,帐号或密码错误");        }        var user = new User        {            Id = 1,            UserId = "abc",            UserName = "小明",            Identity = Identity.User        };        _authManager.SignIn(user);    }    //登出    [HttpPost]    [Route("signOut")]    public void SignOut()    {        _authManager.SignOut();    }    //测试是否通过验证    [HttpPost]    [Route("isAuthenticated")]    public bool IsAuthenticated()    {        var user = _authManager.GetUser();        if (user == null)        {            return false;        }        return true;    }}

最后要在 Web.config 内加入 <authentication mode="Forms" /> 才会启用表单验证。

<configuration>  <system.web>    <!--启用Form认证-->    <authentication mode="Forms" />  </system.web></configuration>

测试

接着使用 Postman 测试。

1.登入

api/auth/signIn

.ASPXAUTH 就是表单验证使用的 Cookie。

http://img2.58codes.com/2024/20106865sfjR7TSCa7.jpg

2.是否通过验证

api/auth/isAuthenticated

回传 true 表示成功登入。

http://img2.58codes.com/2024/20106865HM7WPvVoWf.jpg

3.登出

api/auth/signOut

可以看到 Cookie 少了一个,.ASPXAUTH 被清除了。

http://img2.58codes.com/2024/20106865pGA4BzIVp9.jpg

4.是否通过验证

api/auth/isAuthenticated

回传 false 表示成功登出。

http://img2.58codes.com/2024/20106865FiWWk8iJlC.jpg

结语

表单验证帮我们处理了加解密和 Cookie 的操作,因此很容易就完成了网站的登入机制,AuthManager 使用 JSON 储存使用者资讯,JSON 容易扩展,未来如需增加 Cookie 资讯,只需对 User 类别新增栏位即可,不过还是要注意 Cookie 的长度限制,各家浏览器不太一样,大概是 4K 左右,今天就介绍到这里,感谢大家观看。

参考文章

[ASP.NET WebApi]使用JWT进行web api验证
浅谈使用Json Web Token和Cookie的利弊
简介 ASP.NET 表单验证 (FormsAuthentication) 的运作方式
ASP.NET 自订角色的方式(不用实做 Role Provider)
[ASP.net MVC] ASP.net MVC整合FormsAuthentication表单验证登入 - 简易範例程式码
请问有关Context.User.Identity 与 Request.IsAuthenticated 之间的问题
UserManager(Of TUser) 类别


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章