什么是找出如果用户在WEB MVC API登录的正确方法? [英] What is the correct way of find out if user is logged in in MVC WEB API?

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

问题描述

我对这个问题很困惑。 REST风格的服务让你来决定实施此functionallity哪种方式。

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.

例如有些人propopse会话,但如果你这样做的Web API正在失去它的休息丰满。其他人建议cockies。

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:

在用户登录我创建一个包含用户名(GUID)和cockie每一个需要用户先登录我检查,如果该ID在DB exsists请求。

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; }
}

网络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.

这是一个从真正的应用程序的例子,但我希望这个想法是明确的:)

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

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