第一节: 基本介绍django
1. REST框架中, 因为是先后端分离, 因此已是跨站点访问, 因此csrf认证也就不必作了. segmentfault
框架中的 BasicAuthentication 和 SessionAuthentication 这两个类实际上也没干啥事, 仍然是利用django自己的 SessionMiddleware 和 AuthenticationMiddleware 这两个中间件后端
那么, REST中的认证有什么特别的地方吗? 有! 在于其本身的 TokenAuthentication 类api
2. 首先是注册app浏览器
INSTALLED_APPS = [ ... 'rest_framework.authtoken' ]
3. 使用 makemigrations 和 migrate 生成 token 表, 这个表只有3个字段, user_id 外键到咱们的userprofile表app
3.实际上 token 和 user 是一一对应的, 但token不会自动建立, 因此须要单独的配置, 配置以下,框架
每次用户注册的时候, 咱们都应该调用这个函数前后端分离
用户登陆的时候, 也会自动生成tokenide
from rest_framework.authtoken.models import Token token = Token.objects.create(user=...) print(token.key)
4.另外, 浏览器端的用户认证, 应该带上如下头信息函数
Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b #中间有空格
5.最后是url的配置
from rest_framework.authtoken import views urlpatterns += [ url(r'^api-token-auth/', views.obtain_auth_token) ]
6.配置好后, 使用google浏览器的SERVISTATE插件来进行post测试
(以前没加X-CSRFTOKEN, 参考这个才弄成了 https://segmentfault.com/a/1190000016493704 和 https://segmentfault.com/a/1190000000764598 )
7.额外的, 能够发现, drf的authtoken在检查到用户发起请求时, 但用户若是没有token, 则会自动给用户生成token
第二节: 携带Token去访问
1. 有了前面的分析, 咱们已经知道一个用户有一个Token, 而drf因为先后端分离的特性, 因此使用其本身的独特的token验证机制, 只要在访问的时候带上Token, 服务端就能够肯定用户是谁, 接下来去验证一下
咱们在ListModelMixin里面的queryset这里打断点, 并使用get发送一个请求
2. 从上面的结果来看, 对于普通请求, 服务端没有用户信息, 接下来去测试带上Token的值结果会是怎样
3. django是如何将user封装进来的,这个就须要对django的流程有所了解了, 转载 http://www.projectsedu.com/archives/ django从请求到返回都经历了什么
另外, REST是如何给用户生成Token的, 看下面的源码
urls中的views.obtain_auth_token.ObtainAuthToken ... def post(self, request, *args, **kwargs): serializer = self.serializer_class(data=request.data, context={'request': request}) serializer.is_valid(raise_exception=True) user = serializer.validated_data['user'] token, created = Token.objects.get_or_create(user=user) return Response({'token': token.key})
重点:
4. 如今有这么一种状况, 假设全局当中只有Goodslist接口是一个须要登录后才能访问的接口, 那么咱们前面的设置又是一个全局的Token检查, 怎么样才能达到对某一个接口实时单独的Token认证呢?
方法就是把Token认证移动到对应的View函数内部, 同时删掉全局Token认证
goods.view.py from rest_framework.authentication import TokenAuthentication class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): ... authentication_classes = [TokenAuthentication,] # 对goodslist接口单独设置Token认证 ...
----- 君子处其实,不处其华;治其内,不治其外 张居正 ------