博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Nancy跨平台开发总结(六)三层架构之Token认证的Rest API
阅读量:5156 次
发布时间:2019-06-13

本文共 5401 字,大约阅读时间需要 18 分钟。

在开始写本节内容前,我使用Nancy.Authentication.Token实现的Token认证,但是就在我开始写本节内容的时,我看到Nancyfx的文档中的内容更新

所以我改为使用Nancy.Authentication.Stateless自己实现Token认证

  • 新一个空的Asp.net Web项目,添加Nuget包
    •  Owin
    • Nancy
    • Nancy.Owin
    • Nancy.Bootstrappers.Autofac
    • Microsoft.Owin.Host.SystemWeb
    • Nancy.Authentication.Stateless
    • EntityFramework
    • Mysql.Data
    • Mysql.Data.Entity
  • 从上一节中的WebSite项目中拷贝以下几个文件,修改命名空间,修改Bootstrapper去掉Form认证的相关代码

  • 在Models文件夹下新建一个AuthModel类文件,代码如下
    using System.Collections.Generic;using Nancy.Security;using Nop.Core.Caching;namespace WebSite.WebApi.Models{    ///     /// 代表经过认证的用户    ///     public class UserIdentity : IUserIdentity    {        public UserIdentity(string userName) :            this(userName, new List
    ()) { } public UserIdentity(string userName, IEnumerable
    claims) { this.UserName = userName; this.Claims = claims; } public IEnumerable
    Claims { get; private set; } public string UserName { get; private set; } } ///
    /// 包含生成token和校验token的静态方法 /// public class UserMapper { private static readonly MemoryCacheManager manager = new MemoryCacheManager(); ///
    /// 根据token获取用户信息,检测用户是否有效 /// ///
    ///
    public static IUserIdentity GetUserFromAccessToken(string token) { if (string.IsNullOrEmpty(token)) { return null; } return manager.Get
    (token); } ///
    /// 生成一个新的token,并缓存 /// ///
    ///
    public static string GenerateToken(string userName) { string token= Guid.NewGuid().ToString(); //token有效期 manager.Set(token, new UserIdentity(userName),60*24); return token; } }}
  • 在Bootstrapper的RequestStartup事件中添加配置stateless认证.
    pipelines.AfterRequest.AddItemToEndOfPipeline(x =>            {                x.Response.Headers.Add("Access-Control-Allow-Origin", "*");                x.Response.Headers.Add("Access-Control-Allow-Methods", "POST,GET,DELETE,PUT,OPTIONS");            });var configuration =new StatelessAuthenticationConfiguration(nancyContext =>               {                //返回null代码token无效或用户未认证                  string token =       nancyContext.Request.Headers.Authorization;                  if (!string.IsNullOrEmpty(token))                  {                      return UserMapper.GetUserFromAccessToken(token);                  }                  else                  {                      return null;                  }               }); StatelessAuthentication.Enable(pipelines, configuration);
  • 在UserService中添加根据Id查找用户信息的方法,并在IUserService中添加对应接口
    /// /// Gets the User by identifier./// /// 
    The User by identifier.
    /// Identifier.public virtual User GetUserById(int id){  if (id == 0) return null; string key = string.Format(Users_BY_ID_KEY, id); var user = _cacheManager.Get(key, () => userRepository.GetById(id)); return user;}
  • 在Controller中建一个类AuthController类,用于验证用户并生成Token,代码如下
    private IUserService service;public AuthController(IUserService service) : base("token"){     this.service = service;     Post["/"] = x =>     {         var user = this.Bind
    (); return GetToken(user.UserName, user.Password); };}private object GetToken(string username, string password){ DataResult
    result = service.ValidateUser(username, password); if (result.Result == 0) {  return new { error = "认证失败!", error_description = result.Message, }; } else { return new { access_token = UserMapper.GenerateToken(username), }; }}
  • 添加UserController,根据Id获取用户信息,并限定访问接口必须认证后才能使用
    public class UserController:NancyModule{        private IUserService service;        public UserController(IUserService service):base("api/user")        {            //限制认证            this.RequiresAuthentication();            this.service = service;          //异步模型            Get["/{Id}", true] = async (_, ct) =>            {                User user = await Task.Run(() =>                {                    return service.GetUserById(_.Id);                });                return user;            };        }}
  • 建一个WebSite.Test的控制台应用程序,通过nuget添加RestSharp引用包,在Main函数中添加以下代码测试接口
    RestClient client = new RestClient("http://localhost:56751");string result = string.Empty;var request = new RestRequest("/token");var body = new{       grant_type = "password",       username = "admin",       password = "1234567"};request.AddObject(body);IRestResponse response = client.Post(request);result = response.Content;dynamic content = SimpleJson.DeserializeObject(result); ;if (response.StatusCode != HttpStatusCode.OK){       string error = content.error_description;       return;}string token = content.access_token;var request2 = new RestRequest("/api/user/1");request2.AddHeader("Authorization", token);IRestResponse response2 = client.Get(request2);if (response2.StatusCode == HttpStatusCode.OK){    result = response2.Content;}

     

 

转载于:https://www.cnblogs.com/lpush/p/5234712.html

你可能感兴趣的文章
UVA 10480 Sabotage
查看>>
2C. Fibonacci Again
查看>>
BNUOJ 7178 病毒侵袭持续中
查看>>
Flex 布局教程:语法篇
查看>>
从零开始徒手撸一个vue的toast弹窗组件
查看>>
7Z命令行
查看>>
如何将网站升级为HTTPS协议(整理)
查看>>
amazeui学习笔记--css(布局相关2)--等分网格 AVG Grid
查看>>
php面向对象之get和set方法
查看>>
P1091 合唱队形
查看>>
Html概述
查看>>
C++编程模板2
查看>>
Python教程:丛入门到实践
查看>>
防止IE不支持console.log报错
查看>>
Python通过正则表达式去除(过滤)HTML标签,提取文字
查看>>
https://gogs.io/
查看>>
diskData磁盘数据分析
查看>>
洛谷 P1508 Likecloud-吃、吃、吃
查看>>
linux下面实时查看进程,内存以及cpu使用情况使用命令
查看>>
eclipse改变默认的编码格式(UTF-8)
查看>>