近些天,看了一些博客园大牛关于webApi项目的的文章,也有请教师兄一些问题,自己做了个Demo试了试,收获甚多。感谢感谢,下面是我一些学习的总结,如若有错的地方请多多指教!!

WebApi登陆与身份验证

因为在调用接口的时候都必须传sessionKey参数过去,所以必须先登录验证身份。

如果是已注册用户则账号登陆,获得其身份标识的 sessionkey,如果是非账户用户则可以匿名登陆,要输入用户IP地址或者和客户端设备号等以获得sessionkey,然后可以去注册。

 

#region  登录API
/// <summary>
/// 登录API (账号登陆)
/// </summary>
/// <param name="phone">登录帐号手机号</param>
/// <param name="hashedPassword">加密后的密码,这里避免明文,客户端加密后传到API端</param>
/// <param name="deviceType">客户端的设备类型</param>
/// <param name="clientId">客户端识别号, 一般在APP上会有一个客户端识别号</param>
/// <returns></returns>
[Route("account/login")]
public SessionObject Login(string phone, string hashedPassword, int deviceType = , string clientId = "") {
if (string.IsNullOrEmpty(phone))
throw new ApiException("用户名不能为空。", "RequireParameter_userphone");
if (string.IsNullOrEmpty(hashedPassword))
throw new ApiException("hashedPassword 不能为空.", "RequireParameter_hashedPassword"); int timeout = ; var nowUser = _authenticationService.GetUserByPhone(phone);
if (nowUser == null)
throw new ApiException("帐户不存在", "Account_NotExits"); #region 验证密码
if (!string.Equals(nowUser.Password, hashedPassword)) {
throw new ApiException("错误的密码", "Account_WrongPassword");
}
#endregion if (!nowUser.IsActive)
throw new ApiException("用户处于非活动状态.", "InactiveUser"); UserDevice existsDevice = _authenticationService.GetUserDevice(nowUser.UserId, deviceType); if (existsDevice == null) {
string passkey = MD5CryptoProvider.GetMD5Hash(nowUser.UserId + nowUser.Phone + DateTime.UtcNow+ Guid.NewGuid());
existsDevice = new UserDevice() {
UserId = nowUser.UserId,
CreateTime = DateTime.UtcNow,
ActiveTime = DateTime.UtcNow,
ExpiredTime = DateTime.UtcNow.AddMinutes(timeout),
DeviceType = deviceType,
SessionKey = passkey
};
_authenticationService.AddUserDevice(existsDevice);
}
else {
existsDevice.ActiveTime = DateTime.UtcNow;
existsDevice.ExpiredTime = DateTime.UtcNow.AddMinutes(timeout);
_authenticationService.UpdateUserDevice(existsDevice);
}
nowUser.Password = "";
return new SessionObject() { SessionKey = existsDevice.SessionKey, LogonUser = nowUser };
}
#endregion

登录API

        #region 匿名登陆
/// <summary>
/// 匿名登陆
/// </summary>
/// <param name="ip">用户ip地址</param>
/// <param name="deviceType">设备类型</param>
/// <param name="clientId">客户端识别号</param>
/// <returns></returns>
[Route("account/AnonymousLogin")]
public SessionObject1 AnonymousLogin(string ip, int deviceType = , string clientId = "")
{
if (string.IsNullOrEmpty(ip))throw new ApiException("ip地址不能为空。", "RequireParameter_ip"); int timeout = ; UserDevice existsDevice = _authenticationService.GetUserDevice(ip, deviceType);
// Session.QueryOver<UserDevice>().Where(x => x.AccountId == nowAccount.Id && x.DeviceType == deviceType).SingleOrDefault();
if (existsDevice == null) {
string passkey = MD5CryptoProvider.GetMD5Hash(ip+DateTime.UtcNow + Guid.NewGuid());
existsDevice = new UserDevice() {
IP = ip,
CreateTime = DateTime.UtcNow,
ActiveTime = DateTime.UtcNow,
ExpiredTime = DateTime.UtcNow.AddMinutes(timeout),
DeviceType = deviceType,
SessionKey = passkey
};
_authenticationService.AddUserDevice(existsDevice);
}
else {
existsDevice.ActiveTime = DateTime.UtcNow;
existsDevice.ExpiredTime = DateTime.UtcNow.AddMinutes(timeout);
_authenticationService.UpdateUserDevice(existsDevice);
}
return new SessionObject1() { SessionKey = existsDevice.SessionKey, Ip=ip };
} #endregion

匿名登陆

身份信息的认证是通过Web API 的 ActionFilter来实现的,所有需要身份验证的API请求都会要求客户端传一个SessionKey。

在这里我们通过一个自定义的SessionValidateAttribute来做客户端的身份验证, 其继承自 System.Web.Http.Filters.ActionFilterAttribute。

    public class SessionValidateAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
public const string SessionKeyName = "SessionKey";
public const string LogonUserName = "LogonUser"; public override void OnActionExecuting(HttpActionContext filterContext)
{
var qs = HttpUtility.ParseQueryString(filterContext.Request.RequestUri.Query);
string sessionKey = qs[SessionKeyName]; if (string.IsNullOrEmpty(sessionKey))
{
throw new ApiException("无效 Session.", "InvalidSession");
} IAuthenticationService authenticationService = new AuthenticationService();//IocManager.Intance.Reslove<IAuthenticationService>(); //验证用户session
var userSession = authenticationService.GetUserDevice(sessionKey); if (userSession == null)
{
throw new ApiException("无此 sessionKey", "RequireParameter_sessionKey");
}
else
{
//todo: 加Session是否过期的判断
if (userSession.ExpiredTime < DateTime.UtcNow)
throw new ApiException("session已过期", "SessionTimeOut"); var logonUser = authenticationService.GetUser(userSession.UserId);
if (logonUser != null)
{
filterContext.ControllerContext.RouteData.Values[LogonUserName] = logonUser;
SetPrincipal(new UserPrincipal<int>(logonUser));
}
userSession.ActiveTime = DateTime.UtcNow;
userSession.ExpiredTime = DateTime.UtcNow.AddMinutes();
authenticationService.UpdateUserDevice(userSession);
}
} public static void SetPrincipal(IPrincipal principal)
{
Thread.CurrentPrincipal = principal;
if (HttpContext.Current != null)
{
HttpContext.Current.User = principal;
}
}
}

API身份验证

需要身份验证的apiControler 上加上[sessionValidate],则这个Controller下面所有Action都将拥有身份验证功能

如果是需要管理员权限才能请求的数据的话,那么我们再定义一个 SessionValidateAdminAttribute 来做管理员的身份验证,在需要管理员权限才能请求的控制器上加上[SessionValidateAdminAttribute ],则这个控制器下面所有Action都只有通过身份验证的管理员才有权限请求。

public class SessionValidateAdminAttribute : System.Web.Http.Filters.ActionFilterAttribute {
public const string SessionKeyName = "SessionKey";
public const string LogonUserName = "LogonUser"; public override void OnActionExecuting(HttpActionContext filterContext) {
var qs = HttpUtility.ParseQueryString(filterContext.Request.RequestUri.Query);
string sessionKey = qs[SessionKeyName]; if (string.IsNullOrEmpty(sessionKey)) {
throw new ApiException("无效 Session.", "InvalidSession");
} IAuthenticationService authenticationService = new AuthenticationService();//IocManager.Intance.Reslove<IAuthenticationService>(); //验证用户session
var userSession = authenticationService.GetUserDevice(sessionKey); if (userSession == null) {
throw new ApiException("无此 sessionKey", "RequireParameter_sessionKey");
}
else {
//todo: 加Session是否过期的判断
if (userSession.ExpiredTime < DateTime.UtcNow)
throw new ApiException("session已过期", "SessionTimeOut"); var logonUser = authenticationService.GetUser(userSession.UserId); if (logonUser == null) {
throw new ApiException("无此用户", "Invalid_User");
}
else
{
if (logonUser.Permissions == )
{
filterContext.ControllerContext.RouteData.Values[LogonUserName] = logonUser;
SessionValidateAttribute.SetPrincipal(new UserPrincipal<int>(logonUser));
}
else
{
throw new ApiException("用户无权限", "No permissions");
}
}
userSession.ActiveTime = DateTime.UtcNow;
userSession.ExpiredTime = DateTime.UtcNow.AddMinutes();
authenticationService.UpdateUserDevice(userSession);
}
} }

SessionValidateAdminAttribute

关于:[EnableCors(origins: "*", headers: "*", methods: "*")] 的说明,

详情查看:http://www.cnblogs.com/artech/p/cors-4-asp-net-web-api-05.html

关于用户过期时间:每次调用接口的时候 会自动更新sessionKey的过期时间,如果长时间未更新,则下次访问时会过期,则需要重新登陆。

加入身份验证后的 UserControler

[EnableCors(origins: "*", headers: "*", methods: "*")]
[RoutePrefix("api/Users"), SessionValidate, WebApiTracker]
public class UsersController : ApiController
{
private readonly IUsers _users=new UsersImpl();
#region 根据用户ID获得用户信息
/// <summary>
/// 根据用户ID获得用户信息(获得数据)
/// </summary>
/// <param name="sessionKey">sessionKey</param>
/// <param name="id">用户id</param>
/// <returns>result</returns>
public ApiResult<Users> GetUserById( string sessionKey,int id)
{
Users modelUsers = _users.GetUserByUsersId(id);
if (modelUsers != null)
{
return new ApiResult<Users>("","获取用户信息成功",modelUsers);
}
else return new ApiResult<Users>("","无此用户信息",null);
}
#endregion /// <summary>
/// 新用户注册(增加数据)
/// </summary>
/// <param name="modelUsers"></param>
/// <returns>result</returns>
[HttpPost, Route("api/UserRegistration")]
public ApiResult<bool> UserRegistration(string sessionKey, AddUserRq modelUsers)
{
Users usersModel=new Users();
usersModel.IsActive = true;
usersModel.Password = modelUsers.Password;
usersModel.Permissions = ;
usersModel.Phone = modelUsers.Phone;
usersModel.Sex = modelUsers.Sex;
usersModel.TrueName = modelUsers.TrueName;
usersModel.UserName = modelUsers.UserName;
return _users.RegistrationNewUsers(usersModel);
}
}

UsersControllers

此随笔乃本人学习工作记录,如有疑问欢迎在下面评论,转载请标明出处。

如果对您有帮助请动动鼠标右下方给我来个赞,您的支持是我最大的动力。

2017-11 代码及数据库文件已经上传至 https://github.com/huangenai/WebAPI

学习总结之 WebApi 用户登录和匿名登录,及权限验证的更多相关文章

  1. WebApi用户登录验证及服务器端用户状态存取

    最近项目需要给手机端提供数据,采用WebApi的方式,之前的权限验证设计不是很好,这次采用的是Basic基础认证. 1.常见的认证方式 我们知道,asp.net的认证机制有很多种.对于WebApi也不 ...

  2. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(15)-用户登录详细错误和权限数据库模型设计

    原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(15)-用户登录详细错误和权限数据库模型设计     ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)    ...

  3. Spring MVC学习笔记——完整的用户登录

    1.搭建环境的第一步是导包,把下面这些包都导入工程中 /media/common/工作/Ubuntu软件/SpringMVC_jar包整理/aop/media/common/工作/Ubuntu软件/S ...

  4. Servlet学习(三)——实例:用户登录并记录登陆次数

    1.前提:在Mysql数据库下建立数据库web13,在web13下创建一张表user,插入几条数据如下: 2.创建HTML文件,命名为login,作为登录界面(以post方式提交) <!DOCT ...

  5. Tornado 判断用户登录状态和操作权限(装饰器)

    判断是否登录: def authenticated(method): '''''' @functools.wraps(method) def wrapper(self, *args, **kwargs ...

  6. ant design pro v2 关于用户登录有多个权限的解决方法

    ant design pro V2菜单栏显示流程, 用户输入用户名,密码,登录调用登录接口,校验后返回该用户的权限字段currentAuthority,然后通过调用setAuthority(curre ...

  7. .Net Core3.0 WebApi 项目框架搭建 四:JWT权限验证

    .Net Core3.0 WebApi 项目框架搭建:目录 什么是JWT 根据维基百科定义,JWT(读作 [/dʒɒt/]),即JSON Web Tokens,是一种基于JSON的.用于在网络上声明某 ...

  8. SpringMVC学习系列(9) 之 实现注解式权限验证

    对大部分系统来说都需要权限管理来决定不同用户可以看到哪些内容,那么如何在Spring MVC中实现权限验证呢?当然我们可以继续使用servlet中的过滤器Filter来实现.但借助于Spring MV ...

  9. WebApi -用户登录后SessionId未更新

    描工具检测出.net的程序有会话标识未更新这个漏洞 用户尚未登录时就有session cookie产生.可以尝试在打开页面的时候,让这个cookie过期.等到用户再登陆的时候就会生成一个新的sessi ...

随机推荐

  1. Spark优化之三:Kryo序列化

    Spark默认采用Java的序列化器,这里建议采用Kryo序列化提高性能.实测性能最高甚至提高一倍. Spark之所以不默认使用Kryo序列化,可能的原因是需要对类进行注册. Java程序中注册很简单 ...

  2. CharSequence cannot be resolved. It is indirectly referenced from required .class files

    最近在写项目的时候发现会莫名其妙的出现这个编译错误,网上查了下发现自己安装的是JDK1.8造成的 原因:JDK1.8版本现在还不稳定 解决方法:卸载JDK1.8,安装JDK1.7 扩展:发现安装JDK ...

  3. bzoj2599: [IOI2011]Race(点分治)

    写了四五道点分治的题目了,算是比较理解点分治是什么东西了吧= = 点分治主要用来解决点对之间的问题的,比如距离为不大于K的点有多少对. 这道题要求距离等于K的点对中连接两点的最小边数. 那么其实道理是 ...

  4. 移动端图片上传base64编码

    $base64 = "/9j/4AAQSkZJRgABAQEAkACQAAD/4QCMRXhpZgAATU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAA ...

  5. WDM驱动和NT驱动之我见

    WDM驱动是NT驱动的进化版.我个人觉得它的主要好处有两个 1.能检测到设备的插入,系统能自动分配设备的硬件信息,如中断号.IO端口.设备物理地址等 2.支持设备的开机状态拔出 之前的NT驱动和硬件关 ...

  6. Excel导入导出的业务进化场景及组件化的设计方案(上)

    1:前言 看过我文章的网友们都知道,通常前言都是我用来打酱油扯点闲情的. 自从写了上面一篇文章之后,领导就找我谈话了,怕我有什么想不开. 所以上一篇的(下)篇,目前先不出来了,哪天我异地二次回忆的时候 ...

  7. Webix JavaScript UI 库可以帮你构建跨平台的HTML5 和 CSS3 程序

    XB 软件公司最近发布了JavaScript UI 库Webix ,其中包含的组件超过45个,用这些组件可以构建跟HTML5 和 CSS3 兼容的程序,这些程序不仅能在个人电脑上运行,还能用在iOS. ...

  8. 解读ASP.NET 5 & MVC6系列(3):项目发布与部署

    本章我们将讲解ASP.NET5项目发布部署相关的内容,示例项目以我们前一章创建的BookStore项目为例. 发布前的设置 由于新版ASP.NET5支持多版本DNX运行环境的发布和部署,所以在部署之前 ...

  9. 一步一步学ROP之linux_x64篇

    一步一步学ROP之linux_x64篇 一.序 **ROP的全称为Return-oriented programming(返回导向编程),这是一种高级的内存攻击技术可以用来绕过现代操作系统的各种通用防 ...

  10. Code First开发系列之管理数据库创建,填充种子数据以及LINQ操作详解

    返回<8天掌握EF的Code First开发>总目录 本篇目录 管理数据库创建 管理数据库连接 管理数据库初始化 填充种子数据 LINQ to Entities详解 什么是LINQ to ...