确定用户是否已登录 MVC WEB API 的正确方法是什么? [英] What is the correct way of find out if user is logged in in MVC WEB API?

查看:21
本文介绍了确定用户是否已登录 MVC WEB API 的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对这个问题很困惑.Restfull 服务让您决定以哪种方式实现此功能.

I am very confused about this problem. Restfull service make it up to you to decide which way to implement this functionallity.

我已经阅读了多篇关于这个问题的文章,但每篇文章都说了不同的内容.

Ive read multiple articles about this problem, but every article says something different.

例如,有些人提出会话,但如果您这样做,Web api 将失去其休息充实度".其他人建议自以为是.

For example some people propopse sessions, but if you do that Web api is losing its "rest fullness". Other people suggest cockies.

我不知道我所做的是否正确:

I dont know if what i am done is actually done right:

在用户登录时,我创建一个包含 UserID(Guid) 的 cockie,在需要用户登录的每个请求中,我检查该 ID 是否存在于数据库中.

On login of user i create a cockie which contains UserID(Guid) and on every request which needs user to be logged in i check if this id exsists in the DB.

是否足够安全?或者我应该如何使它更安全?还是我必须选择完全不同的方式?

Is it secure enough? Or how should i make it more secure? Or do i have to choose completly different way?

推荐答案

只需在服务器端创建身份验证令牌并将其存储在您的数据库甚至缓存中.然后将此令牌与来自您的客户端应用程序的请求一起发送.WebApi 应该一直检查这个令牌.这已经足够了,而且您可以完全控制您的身份验证过程.

Just create authentication token on server-side and store it in your database or even in cache. Then send this token with requests from your client application. WebApi should check this token all the time. It's good enough and you have full control over your auth process.

让我分享一下它对我的作用:

Let me share, how it works for me:

具有身份验证详细信息的对象:

public class TokenIdentity
{
    public int UserID { get; set; }

    public string AuthToken { get; set; }

    public ISocialUser SocialUser { get; set; }
}

Web API 身份验证控制器:

  public class AuthController : ApiController
    {
        public TokenIdentity Post(
            SocialNetwork socialNetwork,
            string socialUserID,
            [FromUri]string socialAuthToken,
            [FromUri]string deviceRegistrationID = null,
            [FromUri]DeviceType? deviceType = null)
        {
            var socialManager = new SocialManager();

            var user = socialManager.GetSocialUser(socialNetwork, socialUserID, socialAuthToken);

            var tokenIdentity = new AuthCacheManager()
                .Authenticate(
                    user,
                    deviceType,
                    deviceRegistrationID);

            return tokenIdentity;
        }
    }

身份验证缓存管理器:

public class AuthCacheManager : AuthManager
    {
        public override TokenIdentity CurrentUser
        {
            get
            {
                var authToken = HttpContext.Current.Request.Headers["AuthToken"];
                if (authToken == null) return null;

                if (HttpRuntime.Cache[authToken] != null)
                {
                    return (TokenIdentity) HttpRuntime.Cache.Get(authToken);
                }

                return base.CurrentUser;
            }
        }

        public int? CurrentUserID
        {
            get
            {
                if (CurrentUser != null)
                {
                    return CurrentUser.UserID;
                }
                return null;
            }
        }

        public override TokenIdentity Authenticate(
            ISocialUser socialUser, 
            DeviceType? deviceType = null, 
            string deviceRegistrationID = null)
        {
            if (socialUser == null) throw new ArgumentNullException("socialUser");
            var identity = base.Authenticate(socialUser, deviceType, deviceRegistrationID);

            HttpRuntime.Cache.Add(
                identity.AuthToken,
                identity,
                null,
                DateTime.Now.AddDays(7),
                Cache.NoSlidingExpiration,
                CacheItemPriority.Default,
                null);

            return identity;
        }
    }

身份验证管理器:

 public abstract class AuthManager
    {
        public virtual TokenIdentity CurrentUser
        {
            get
            {
                var authToken = HttpContext.Current.Request.Headers["AuthToken"];
                if (authToken == null) return null;

                using (var usersRepo = new UsersRepository())
                {
                    var user = usersRepo.GetUserByToken(authToken);

                    if (user == null) return null;

                    return new TokenIdentity
                    {
                        AuthToken = user.AuthToken,
                        SocialUser = user,
                        UserID = user.ID
                    };
                }
            }
        }

        public virtual TokenIdentity Authenticate(
            ISocialUser socialUser, 
            DeviceType? deviceType = null, 
            string deviceRegistrationID = null)
        {
            using (var usersRepo = new UsersRepository())
            {
                var user = usersRepo.GetUserBySocialID(socialUser.SocialUserID, socialUser.SocialNetwork);

                user = (user ?? new User()).CopyFrom(socialUser);

                user.AuthToken = System.Guid.NewGuid().ToString();

                if (user.ID == default(int))
                {
                    usersRepo.Add(user);
                }

                usersRepo.SaveChanges();

                return new TokenIdentity
                {
                    AuthToken = user.AuthToken,
                    SocialUser = user,
                    UserID = user.ID
                };
            }
        }
    }

全局操作过滤器:

public class TokenAuthenticationAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
    public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        if (actionContext.Request.RequestUri.AbsolutePath.Contains("api/auth"))
        {
            return;
        }

        var authManager = new AuthCacheManager();

        var user = authManager.CurrentUser;

        if (user == null)
        {
            throw new HttpResponseException(HttpStatusCode.Unauthorized);
        }

        //Updates the authentication
        authManager.Authenticate(user.SocialUser);
    }
}

Global.asax 注册:

GlobalConfiguration.Configuration.Filters.Add(new AuthFilterAttribute());

这个想法是 AuthCacheManager 扩展了 AuthManager 并装饰了它的方法和属性.如果缓存里面什么都没有,那就去检查数据库.

The idea is that AuthCacheManager extends AuthManager and decorates it's methods and properties. If there is nothing inside cache then go check database.

这是一个来自真实应用的例子,但我希望这个想法很清楚:)

这篇关于确定用户是否已登录 MVC WEB API 的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆