创建的token如何交给前端进行使用呢?
在官方文档说明中,将产生的這个token放在header中
TokenAutication认证原理
用户认证成功以后,会在服务端产生一个Token。并且服务端会将這个Token设置在header里面返回给用户。下次用户在进行登陆相关操作,就根据這个Token去Token表查找相应的用户,并把用户名根据Token提取出来。
我们可以在后端通过request.auth获取用户传递过来的token
那么如何通过Token取出用户的呢?先来看看源码:
class TokenAuthentication(BaseAuthentication): keyword = 'Token' model = None def get_model(self): if self.model is not None: return self.model from rest_framework.authtoken.models import Token return Token def authenticate(self, request): auth = get_authorization_header(request).split() # 调用get_authorization_header # auth = ["Token" ,"c4840b5226a65806c586c239345fce66caf12409"] if not auth or auth[0].lower() != self.keyword.lower().encode(): return None if len(auth) == 1: msg = _('Invalid token header. No credentials provided.') raise exceptions.AuthenticationFailed(msg) elif len(auth) > 2: msg = _('Invalid token header. Token string should not contain spaces.') raise exceptions.AuthenticationFailed(msg) try: token = auth[1].decode() # 取出c4840b5226a65806c586c239345fce66caf12409 except UnicodeError: msg = _('Invalid token header. Token string should not contain invalid characters.') raise exceptions.AuthenticationFailed(msg) return self.authenticate_credentials(token) # 然后调用authenticate_credentials def authenticate_credentials(self, key): model = self.get_model() # 返回Token model try: token = model.objects.select_related('user').get(key=key) # 然后通过key获取用户 except model.DoesNotExist: raise exceptions.AuthenticationFailed(_('Invalid token.')) if not token.user.is_active: raise exceptions.AuthenticationFailed(_('User inactive or deleted.')) return (token.user, token) # 返回用户与token
然后,我们到get_authorization_header()方法里面去看看:
def get_authorization_header(request): auth = request.META.get('HTTP_AUTHORIZATION', b'') # AUTHORIZATION這个就是之前服务端返回的,只不过Django会默认加上HTTP if isinstance(auth, text_type): # Work around django test client oddness auth = auth.encode(HTTP_HEADER_ENCODING) return auth # 返回"Token c4840b5226a65806c586c239345fce66caf12409"
经过上述过程,就完成了Token的获取操作。下面,我们来看看,這个Token是如何创建的:
当用户进行登陆以后:
url(r'^api-token-auth/', views.obtain_auth_token)
通过上述接口,进入到试图函数:
class ObtainAuthToken(APIView): throttle_classes = () permission_classes = () parser_classes = (parsers.FormParser, parsers.MultiPartParser, parsers.JSONParser,) renderer_classes = (renderers.JSONRenderer,) serializer_class = AuthTokenSerializer 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}) # 将token返回obtain_auth_token = ObtainAuthToken.as_view()
从上面的分析来看,当用户没有产生Token,DRF则会给该用户生成一个Token。然后将這个Token返回给前端页面进行保存。