www.91084.com

GVKun编程网logo

基于restframework进行token验证(restful token)

24

这篇文章主要围绕基于restframework进行token验证和restfultoken展开,旨在为您提供一份详细的参考资料。我们将全面介绍基于restframework进行token验证的优缺点,

这篇文章主要围绕基于restframework进行token验证restful token展开,旨在为您提供一份详细的参考资料。我们将全面介绍基于restframework进行token验证的优缺点,解答restful token的相关问题,同时也会为您带来c# – 使用Entity Framework进行自引用、C# 解耦EntityFramework进行单元测试、Django REST Framework 批量更新 rest_framework_extensions、Django rest framwork 获取 token 值和前端 token 携带方法的实用方法。

本文目录一览:

基于restframework进行token验证(restful token)

基于restframework进行token验证(restful token)

  一般情况下,进入到web网站主页都需要进行token或者其它验证,不能在没有登录的情况下可以查看主页的内容,在用户输入用户名密码后,进行校验成功,后台会返回一个token,用于用于下次访问主页或其它页面进行用户认证,一旦认证成功就可以访问了。

1、用户获取token

用户向后台API发送用户名和密码进行校验以及获取token。

 methods: {

      loginSubmit(formName) {
        this.$refs[formName].validate(async (valid) => {
          if (valid) {
            const res = await this.$http.post(''login'', this.form);
            const {data, meta: {message, code}} = res.data;
            if (code === 2000) {

              //获取token,将token值存储在localStorage
              localStorage.setItem(''token'', data.token);

              //验证成功后直接跳转到主页
              this.$router.push({name: ''home''});
              //登陆成功提示
              this.$message.success(message)
            } else {
              this.$message.warning(message)
            }

          } else {
            this.$message.warning("用户名或密码不能为空")
          }
        });
      }
    },

2、后台进行验证

class LoginView(APIView):
    authentication_classes = []  # 登陆页面免认证,其余的已经全局配置

    def post(self, request, *args, **kwargs):

        ret = {
            "data": {},
            "meta": {
                "code": 2001,
                "message": "用户名或密码错误"
            }
        }
        user_obj = json.loads(str(request._request.body, encoding=''utf8''))
        username = user_obj.get(''username'')
        password = user_obj.get(''password'')
        if username and password:
            obj = UserInfo.objects.filter(
                username=username, password=password).first()
            if obj:

                token = get_md5(username)
                # 自动去数据库检查,如果没有就创建,否则更新token
                UserToken.objects.update_or_create(user=obj, defaults={''token'': token})
  
                ret["data"]["username"] = username
                ret["data"]["password"] = password
                ret["data"]["token"] = token

                ret["meta"]["code"] = 2000
                ret["meta"]["message"] = "登陆成功"
            else:
                pass
        else:
            pass
        return HttpResponse(json.dumps(ret, ensure_ascii=False))

 

c# – 使用Entity Framework进行自引用

c# – 使用Entity Framework进行自引用

代码代表我的问题的小规模:
public class Category
{
    public Guid CategoryID { get; set; }
    public string Name { get; set; }
    public Guid? ParentID { get; set; }
    public bool IsTop { get; set; }
    public string Description { get; set; }

    public virtual Category parentCategory { get; set; }
}

当我在Entity Framework中使用此类时,它只生成父类和子类的一个关系.

如何在语义上区分属性,并在sql Server中生成两个不同的关系,用于获取所有子类别(子关系的子项(递归自上而下)),另一个用于获取所有父类别(父项的父项) (递归自下而上))?像这样的东西:

public virtual ICollection<Category> childCategories { get; set;} 
public virtual ICollection<Category> parentCategories { get; set;}

我尝试使用模型构建器,但从那里我只能获得一个级别的细节.

解决方法

在我的一个项目中,我遇到了将所有子节点检索到n深度的问题,作为模型中Employee表上的经典主管/员工自引用关系.正如Slauma和Milracle指出的那样,EF不会帮助您在指定父级下检索所有节点到n的深度.但是,我能够在我的存储库中使用 Breadth-first search algorithm来解决这个问题.请注意,我的目标不仅是检索所有子节点,而且要快速执行,因为使用递归LINQ查询需要超过两分钟的时间来进行最高级别的管理.使用此方法,它现在可在不到两秒的时间内执行.
public IEnumerable<string> GetAllSubordinateEmployeeIdsByUserId(string userId)
{
    // Retrieve only the fields that create the self-referencing relationship from all nodes
    var employees = (from e in GetAllEmployees()
                     select new { e.Id,e.SupervisorId });
    // Dictionary with optimal size for searching
    Dictionary<string,string> dicEmployees = new Dictionary<string,string>(employees.Count() * 4);
    // This queue holds any subordinate employees we find so that we may eventually identify their subordinates as well
    Queue<string> subordinates = new Queue<string>();
    // This list holds the child nodes we're searching for
    List<string> subordinateIds = new List<string>();

    // Load the dictionary with all nodes
    foreach (var e in employees)
    {
        dicEmployees.Add(e.Id,e.SupervisorId);
    }

    // Get the key (employee's ID) for each value (employee's supervisor's ID) that matches the value we passed in
    var directReports = (from d in dicEmployees
                         where d.Value == userId
                         select d.Key);

    // Add the child nodes to the queue
    foreach (var d in directReports)
    {
        subordinates.Enqueue(d);
    }

    // While the queue has a node in it...
    while (subordinates.Count > 0)
    {
        // Retrieve the children of the next node in the queue
        var node = subordinates.Dequeue();
        var childNodes = (from e in dicEmployees
                          where e.Value == node
                          select e.Key);
        if (childNodes.Count() != 0)
        {
            // Add the child nodes to the queue
            foreach (var c in childNodes)
            {
                subordinates.Enqueue(c);
            }
        }
        // Add the node from the queue to the list of child nodes
        subordinateIds.Add(node);
    }

    return subordinateIds.AsEnumerable();
}

此外,作为脚注,我在这篇Dictionary optimization文章的帮助下,能够提高字典中的查找效率.

C# 解耦EntityFramework进行单元测试

C# 解耦EntityFramework进行单元测试

1. 首先ef的repository需要抽象的行为提到接口中。

例如 :

public interface IXXXContext : IDisposable
    {
        IXXXContext NewInstance();
// db sets
        DbSet<AAABBB> aaa { get; set; }
...
// common 
Database Database { get; }
        DbContextConfiguration Configuration { get; }
        int SaveChanges();


        Task<int> SaveChangesAsync();


	// store pros
...
        IStorePro1 StorePro1 { get; }
	...
}
登录后复制


然后就可以使用DataContext和TestDataContext实现这个接口。其中TestDataContext是在UT中使用的,DataContext是自动生成的。

TestDataContext还需要以下几个类进行模拟。

 public class TestDbSet<TEntity> : DbSet<TEntity>, IQueryable, IEnumerable<TEntity>, IDbAsyncEnumerable<TEntity>
         where TEntity : class
    {
        ObservableCollection<TEntity> _data;
        IQueryable _query;


        public TestDbSet()
        {
            _data = new ObservableCollection<TEntity>();
            _query = _data.AsQueryable();
        }


        public override TEntity Add(TEntity item)
        {
            _data.Add(item);
            return item;
        }


        public override TEntity Remove(TEntity item)
        {
            _data.Remove(item);
            return item;
        }


        public override TEntity Attach(TEntity item)
        {
            _data.Add(item);
            return item;
        }


        public override TEntity Create()
        {
            return Activator.CreateInstance<TEntity>();
        }


        public override TDerivedEntity Create<TDerivedEntity>()
        {
            return Activator.CreateInstance<TDerivedEntity>();
        }


        public override ObservableCollection<TEntity> Local
        {
            get { return _data; }
        }


        Type IQueryable.ElementType
        {
            get { return _query.ElementType; }
        }


        Expression IQueryable.Expression
        {
            get { return _query.Expression; }
        }


        IQueryProvider IQueryable.Provider
        {
            get { return new TestDbAsyncQueryProvider<TEntity>(_query.Provider); }
        }


        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return _data.GetEnumerator();
        }


        IEnumerator<TEntity> IEnumerable<TEntity>.GetEnumerator()
        {
            return _data.GetEnumerator();
        }


        IDbAsyncEnumerator<TEntity> IDbAsyncEnumerable<TEntity>.GetAsyncEnumerator()
        {
            return new TestDbAsyncEnumerator<TEntity>(_data.GetEnumerator());
        }
    }


    internal class TestDbAsyncQueryProvider<TEntity> : IDbAsyncQueryProvider
    {
        private readonly IQueryProvider _inner;


        internal TestDbAsyncQueryProvider(IQueryProvider inner)
        {
            _inner = inner;
        }


        public IQueryable CreateQuery(Expression expression)
        {
            return new TestDbAsyncEnumerable<TEntity>(expression);
        }


        public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
        {
            return new TestDbAsyncEnumerable<TElement>(expression);
        }


        public object Execute(Expression expression)
        {
            return _inner.Execute(expression);
        }


        public TResult Execute<TResult>(Expression expression)
        {
            return _inner.Execute<TResult>(expression);
        }


        public Task<object> ExecuteAsync(Expression expression, CancellationToken cancellationToken)
        {
            return Task.FromResult(Execute(expression));
        }


        public Task<TResult> ExecuteAsync<TResult>(Expression expression, CancellationToken cancellationToken)
        {
            return Task.FromResult(Execute<TResult>(expression));
        }
    }


    internal class TestDbAsyncEnumerable<T> : EnumerableQuery<T>, IDbAsyncEnumerable<T>, IQueryable<T>
    {
        public TestDbAsyncEnumerable(IEnumerable<T> enumerable)
            : base(enumerable)
        { }


        public TestDbAsyncEnumerable(Expression expression)
            : base(expression)
        { }


        public IDbAsyncEnumerator<T> GetAsyncEnumerator()
        {
            return new TestDbAsyncEnumerator<T>(this.AsEnumerable().GetEnumerator());
        }


        IDbAsyncEnumerator IDbAsyncEnumerable.GetAsyncEnumerator()
        {
            return GetAsyncEnumerator();
        }


        IQueryProvider IQueryable.Provider
        {
            get { return new TestDbAsyncQueryProvider<T>(this); }
        }
    }


    internal class TestDbAsyncEnumerator<T> : IDbAsyncEnumerator<T>
    {
        private readonly IEnumerator<T> _inner;


        public TestDbAsyncEnumerator(IEnumerator<T> inner)
        {
            _inner = inner;
        }


        public void Dispose()
        {
            _inner.Dispose();
        }


        public Task<bool> MoveNextAsync(CancellationToken cancellationToken)
        {
            return Task.FromResult(_inner.MoveNext());
        }


        public T Current
        {
            get { return _inner.Current; }
        }


        object IDbAsyncEnumerator.Current
        {
            get { return Current; }
        }
    }
登录后复制


使用示例:

[TestMethod]
        public void TestMethod1()
        {
            var mockSet = new Mock<DbSet<BLACKLISTED_TICKET>>();
            var mockContext = new Mock<TicketDataContextTest>();
            mockContext.Setup(m => m.BLACKLISTED_TICKET).Returns(new TestDbSet<BLACKLISTED_TICKET>());


            var context = mockContext.Object;


            context.BLACKLISTED_TICKET.Add(new BLACKLISTED_TICKET()
            {
                TicketNumber = "aaa",
                CreatedDateTime = DateTime.Now,
                Id = 1,
                ModifiedDateTime = DateTime.Now,
                STATUS = "1"
            });


            Assert.IsTrue(context.BLACKLISTED_TICKET.First().Id == 1);
        }
登录后复制

如果使用了存储过程,需要额外定义存储过程的接口。
例如:

IStorePro {
...
}


StorePro : IStorePro{
...
}


StoreProFake: IStorePro{


}
登录后复制

然后IDataContext负责返回存储过程的实例

IDataContext{
	...
	IStorePro GetStorePro();
	...
}
登录后复制

 以上就是C# 解耦EntityFramework进行单元测试的内容。

Django REST Framework 批量更新 rest_framework_extensions

Django REST Framework 批量更新 rest_framework_extensions

Django REST framework 是一套基于 Django 框架编写 RESTful 风格 API 的组件。

 其中 mixins 配合 viewsets 能极其方便简化对数据的增删改查,

但本身并没有对数据的批量更新删除,利用 rest_framework_extensions 扩展包可以轻松帮我们实现这些功能。

安装使用

pip install rest_framework_extensions

 

views.py

在视图类中继承 ListUpdateModelMixin

1 from rest_framework_extensions.mixins import ListUpdateModelMixin
2 class ShoppingCartViewSet(ListUpdateModelMixin, viewsets.ModelViewSet):
3     pass

 

settings.py

1 CORS_ALLOW_HEADERS = [''*'']  # 允许的请求头
2 CORS_ORIGIN_ALLOW_ALL = True  # 允许跨域
3 
4 REST_FRAMEWORK_EXTENSIONS = {
5     ''DEFAULT_BULK_OPERATION_HEADER_NAME'': None
6 }

使用浏览器本地测试,在请求头加上:X-BULK-OPERATION: true

使用 patch 方式请求测试成功,状态码 204,不会返回任何东西

 

使用 PUT 方法批量更新

以上在浏览器使用正常,但发现在微信小程序中并不支持 patch 方法,只能用 put 方法。要么重新再写一个 put 接口,要么更改源码。

ctrl 点击查看 ListUpdateModelMixin 码源,果真只有 put 方法。怎么办?

把 patch 方法复制粘贴一份,改名为 put 即可,同样测试成功。

\Lib\site-packages\rest_framework_extensions\bulk_operations\mixins.py

 

对于以上修改。对于没有使用虚拟环境的同学,个人建议不要直接修改源码,一定要把整个包拷到项目目录下再修改。

在项目目录下新建 extra_apps 文件夹,用来存放要修改的第三方包。

再在 settings.py 中添加以下。优先从 extra_apps 文件夹导包。

import os
import sys
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, os.path.join(BASE_DIR, ''extra_apps''))

 微信小程序测试正常

 

 

 

 

Django rest framwork 获取 token 值和前端 token 携带方法

Django rest framwork 获取 token 值和前端 token 携带方法

在进行用户校验时,有多种方法:

1、Cookie:默认可以通过脚本文件获取,容易遭受 XSS 攻击(跨站脚本攻击);所有浏览器会让用户自愿选择是否存储至 cookie。

2、Session:session 会在一定时间内保存在服务器上;当访问增多,会比较占用你服务器的性能。

3、Token:在登录时会发放 Token,类似于 “身份证”,在一些发送要权限校验的请求时,在请求头带上 Token 即可通过验证。特点:方便、安全。

在 Django rest framwork 中 获取 token 的方式:

首先需要在 python manage.py 依次 makemigrations 和 migrate ,

此做法是需要将 django 的后台管理操作的对应表迁移到数据库(mysql 的迁移表如下):

 其中 authtoken_token 会给 auth_user 中的用户登录时发一个独有的 Token,

前端登录时,需要请求 Token 的 url 为:

需要注意的是一定是 POST 请求,当然了 账号密码一定要对,需要在 auth_user 中相对应数据;

在前端使用 sessionStorage 将 Token 储存下来:

登出时 sessionStorage.removeItem (''token''),清空 token。

使用 ajax 提交时:

Token 放在 ajax 的请求头 headers 中 且需要声明如下图

在后台进行登录判断的具体代码:

request.user.is_authenticated 会校验用户返回是否登录的布尔值。

 

关于基于restframework进行token验证restful token的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于c# – 使用Entity Framework进行自引用、C# 解耦EntityFramework进行单元测试、Django REST Framework 批量更新 rest_framework_extensions、Django rest framwork 获取 token 值和前端 token 携带方法等相关内容,可以在本站寻找。

本文标签: