学习总结之 WebApi 用户登录和匿名登录,及权限验证
近些天,看了一些博客园大牛关于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 用户登录和匿名登录,及权限验证的更多相关文章
- WebApi用户登录验证及服务器端用户状态存取
最近项目需要给手机端提供数据,采用WebApi的方式,之前的权限验证设计不是很好,这次采用的是Basic基础认证. 1.常见的认证方式 我们知道,asp.net的认证机制有很多种.对于WebApi也不 ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(15)-用户登录详细错误和权限数据库模型设计
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(15)-用户登录详细错误和权限数据库模型设计 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) ...
- Spring MVC学习笔记——完整的用户登录
1.搭建环境的第一步是导包,把下面这些包都导入工程中 /media/common/工作/Ubuntu软件/SpringMVC_jar包整理/aop/media/common/工作/Ubuntu软件/S ...
- Servlet学习(三)——实例:用户登录并记录登陆次数
1.前提:在Mysql数据库下建立数据库web13,在web13下创建一张表user,插入几条数据如下: 2.创建HTML文件,命名为login,作为登录界面(以post方式提交) <!DOCT ...
- Tornado 判断用户登录状态和操作权限(装饰器)
判断是否登录: def authenticated(method): '''''' @functools.wraps(method) def wrapper(self, *args, **kwargs ...
- ant design pro v2 关于用户登录有多个权限的解决方法
ant design pro V2菜单栏显示流程, 用户输入用户名,密码,登录调用登录接口,校验后返回该用户的权限字段currentAuthority,然后通过调用setAuthority(curre ...
- .Net Core3.0 WebApi 项目框架搭建 四:JWT权限验证
.Net Core3.0 WebApi 项目框架搭建:目录 什么是JWT 根据维基百科定义,JWT(读作 [/dʒɒt/]),即JSON Web Tokens,是一种基于JSON的.用于在网络上声明某 ...
- SpringMVC学习系列(9) 之 实现注解式权限验证
对大部分系统来说都需要权限管理来决定不同用户可以看到哪些内容,那么如何在Spring MVC中实现权限验证呢?当然我们可以继续使用servlet中的过滤器Filter来实现.但借助于Spring MV ...
- WebApi -用户登录后SessionId未更新
描工具检测出.net的程序有会话标识未更新这个漏洞 用户尚未登录时就有session cookie产生.可以尝试在打开页面的时候,让这个cookie过期.等到用户再登陆的时候就会生成一个新的sessi ...
随机推荐
- [Android] 时间Time Date 以及Location中gettime
import android.text.format.Time; 还有一个是Date Location中的gettime, 这几个每个默认的格式都不一样,直接输出字符串各自得到了不同 比如按照获取当前 ...
- TLV(类型—长度—值)格式及编码
转自: http://www.cnblogs.com/tml839720759/archive/2014/07/13/3841820.html 引子: 前段时间在项目中第一次接触TLV,项目中用这种格 ...
- 后台PageVo中字段赋值与前台datagrid字段获取
后台PageVo中字段的geter与setter函数需根据pageVo的字段自动生成,前台字段与后台字段名保持一致. 数据返回到前台时,datagrid会根据字段名隐射到相应的getter与sette ...
- USACO翻译:USACO 2012 JAN三题(3)
USACO 2012JAN(题目三) 一.题目概览 中文题目名称 放牧 登山 奶牛排队 英文题目名称 grazing climb lineup 可执行文件名 grazing climb lineup ...
- Oracle EBS - Doc
Oracle EBS spec.: http://vianet/IT/IT%20Dept/IT%20Project%20Update2/Active%20Projects%20%20Manufactu ...
- SQL Server通过File Header Page来进行Crash Recovery
SQL Server通过File Header Page来进行Crash Recovery 看了盖总的一篇文章 http://www.eygle.com/archives/2008/11/oracle ...
- ABP理论学习之Web API控制器(新增)
返回总目录 本篇目录 介绍 AbpApiController基类 本地化 审计日志 授权 工作单元 其他 介绍 ABP通过Abp.Web.ApiNuget包集成了 ASP.NET Web API控制器 ...
- ABP理论学习之EntityFramework集成
返回总目录 本篇目录 Nuget包 创建DbContext 仓储 仓储基类 实现仓储 自定义仓储方法 阅读其他 ABP可以使用任何ORM框架工作,并且已经内置了EntityFramework集成.这篇 ...
- Lesson 13 The Greenwood Boys
Text The Greenwood Boys are group of pop singers. At present, they are visiting all parts of the cou ...
- (DNS被劫持所导致的)QQ音乐与视频网页打开很慢的解决方法
这周开始发现一个很让人抓狂的现象,QQ音乐网页(http://y.qq.com)与QQ视频(http://v.qq.com/)网页打开超慢,甚至是无法打开,严重影响了业余的音乐视频生活. 以QQ视频为 ...