学习总结之 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 = 0, string clientId = "") {
            if (string.IsNullOrEmpty(phone))
                throw new ApiException("用户名不能为空。", "RequireParameter_userphone");
            if (string.IsNullOrEmpty(hashedPassword))
                throw new ApiException("hashedPassword 不能为空.", "RequireParameter_hashedPassword");

            int timeout = 60;

            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 = 0, string clientId = "")
        {
            if (string.IsNullOrEmpty(ip))throw new ApiException("ip地址不能为空。", "RequireParameter_ip");

            int timeout = 60;

            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(60);
                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 == 1)
                    {
                        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(60);
                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>("1","获取用户信息成功",modelUsers);
            }
            else return new ApiResult<Users>("0","无此用户信息",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 = 2;
            usersModel.Phone = modelUsers.Phone;
            usersModel.Sex = modelUsers.Sex;
            usersModel.TrueName = modelUsers.TrueName;
            usersModel.UserName = modelUsers.UserName;
            return _users.RegistrationNewUsers(usersModel);
        }
    }

UsersControllers

时间: 2024-08-03 08:12:48

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

简单实现 Webapi 用户登录访问权限

总结一下上一个项目中对webapi 用户登录权限控制的设计 目的:前端可以根据接口的状态码来判断用户的登录状态,以及访问权限 1.首先我们在webconfig里面添加一条配置,用于开启或关闭权限控制 <appSettings> <add key="WebApiAuthFlag" value="true" /> </appSettings> 2.先了解一下 ActionFilterAttribute 这个类,该类可以在action方

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

对大部分系统来说都需要权限管理来决定不同用户可以看到哪些内容,那么如何在Spring MVC中实现权限验证呢?当然我们可以继续使用servlet中的过滤器Filter来实现.但借助于Spring MVC中的action拦截器我们可以实现注解式的权限验证. 一.首先介绍一下action拦截器: HandlerInterceptor是Spring MVC为我们提供的拦截器接口,来让我们实现自己的处理逻辑,HandlerInterceptor 的内容如下: public interface Handl

Linux学习笔记(四)之用户登录

1.Linux是一个网络操作系统,作为多用户,多任务的操作系统,其系统资源是所有用户共享的.任何要使用系统资源者必须先在系统内登记,注册,即开设用户账号,该账号又包含用户名,口令,所用的shell,使用权限等.为了计算机系统的安全,LInux会对每一个要求进入系统的用户进行用户名和口令的验证,如果验证成功则用户登录成功,否则系统拒绝登录. 2.其中用户登录又分为两种,一种是用户的终端登录,另外一种是远程登录,如果用户是在本地终端登录Linux系统,便为用户的终端登录,如果用户是通过网络登录Lin

python3.5学习之路_day1_用户登录

1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #by anthor zhangxiaoyu 2017-01-10 4 #blog:http://www.cnblogs.com/gushiren/ 5 6 import getpass 7 username = "zhangxiaoyu" 8 password = "www.123" 9 count = 3 10 for i in range(3): 11 userna

Python学习笔记1:用户登录

1 import getpass,sys 2 u=0 3 while u< 3: 4 user_name = input('Please input you name:') 5 # user_passwd = getpass.getpass('Please input you password:') 6 lock_file = open('C:/安装包/pycharm/day01/user_lock.txt','r+') 7 lock_line = lock_file.readlines() 8

Web用户的身份验证及WebApi权限验证流程的设计和实现

前言:Web 用户的身份验证,及页面操作权限验证是B/S系统的基础功能,一个功能复杂的业务应用系统,通过角色授权来控制用户访问,本文通过Form认证,Mvc的Controller基类及Action的权限验证来实现Web系统登录,Mvc前端权限校验以及WebApi服务端的访问校验功能. 1. Web Form认证介绍 Web应用的访问方式因为是基于浏览器的Http地址请求,所以需要验证用户身份的合法性.目前常见的方式是Form认证,其处理逻辑描述如下:1. 用户首先要在登录页面输入用户名和密码,然

Web用户的身份验证及WebApi权限验证流程的设计和实现(尾)

5. WebApi 服务端代码示例 5.1 控制器基类ApiControllerBase [csharp] view plaincopy /// /// Controller的基类,用于实现适合业务场景的基础功能 /// /// [BasicAuthentication] public abstract class ApiControllerBase : ApiController { } 5.2 权限属性BaseAuthenticationAttribute [csharp] view pla

[置顶] Web用户的身份验证及WebApi权限验证流程的设计和实现

转发 http://blog.csdn.net/besley/article/details/8516894 [置顶] Web用户的身份验证及WebApi权限验证流程的设计和实现 2013-01-18 13:19 22755人阅读 评论(19) 收藏 举报  分类: Asp.net Web技术(9)  WebAPI(3)  MVC(6)  版权声明:本文为博主原创文章,未经博主允许不得转载. 前言:Web 用户的身份验证,及页面操作权限验证是B/S系统的基础功能,一个功能复杂的业务应用系统,通过

WebApi权限验证流程的设计和实现

前言:Web 用户的身份验证,及页面操作权限验证是B/S系统的基础功能,一个功能复杂的业务应用系统,通过角色授权来控制用户访问,本文通过Form认证,Mvc的Controller基类及Action的权限验证来实现Web系统登录,Mvc前端权限校验以及WebApi服务端的访问校验功能. 1. Web Form认证介绍 Web应用的访问方式因为是基于浏览器的Http地址请求,所以需要验证用户身份的合法性.目前常见的方式是Form认证,其处理逻辑描述如下:1. 用户首先要在登录页面输入用户名和密码,然