def validate(self, attrs):
        authenticate_kwargs = {
            self.username_field: attrs[self.username_field],
            'password': attrs['password'],
            self.identifier_field: attrs[self.identifier_field]
        }
        try:
            authenticate_kwargs['request'] = self.context['request']
        except KeyError:
            pass

        self.user = authenticate(**authenticate_kwargs)

        if self.user is None:
            raise AuthenticationFailed(
                self.default_error_messages['no_active_account'],
                'no_active_account'
            )
        return {}
Beispiel #2
0
    def create_action(self, request, serializer):
        with statsd.timer('auth.browserid.verify'):
            profile, msg = browserid_authenticate(
                request,
                serializer.data['assertion'],
                browserid_audience=serializer.data['audience']
                or get_audience(request),
                is_mobile=serializer.data['is_mobile'],
            )
        if profile is None:
            # Authentication failure.
            log.info('No profile: %s' % (msg or ''))
            raise AuthenticationFailed('No profile.')

        request.user = profile
        request.groups = profile.groups.all()

        auth.login(request, profile)
        profile.log_login_attempt(True)  # TODO: move this to the signal.
        user_logged_in.send(sender=profile.__class__,
                            request=request,
                            user=profile)

        # We want to return completely custom data, not the serializer's.
        data = {
            'error': None,
            'token': commonplace_token(request.user.email),
            'settings': {
                'display_name': request.user.display_name,
                'email': request.user.email,
            }
        }
        # Serializers give up if they aren't passed an instance, so we
        # do that here despite PermissionsSerializer not needing one
        # really.
        permissions = PermissionsSerializer(context={'request': request},
                                            instance=True)
        data.update(permissions.data)

        # Add ids of installed/purchased/developed apps.
        data['apps'] = user_relevant_apps(profile)

        return data
Beispiel #3
0
    def partial_update(self, request, pk=None):
        auth_token = self.request.user
        try:
            decoded_token = jwt.decode(auth_token,
                                       options={"verify_signature": False})
        except (jwt.DecodeError, jwt.InvalidAlgorithmError):
            raise AuthenticationFailed('Bad Token')

        phone = decoded_token['phone_number']
        u = User.objects.filter(phone=phone)

        queryset = Employee.objects.all()
        emp = queryset.filter(id=pk)
        serializer = EmployeeSerializer(emp[0],
                                        data=self.request.data,
                                        partial=True)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data)
Beispiel #4
0
    def post(self, request):
        # 전달받은 데이터에서 usernmae, passqord 추출
        username = request.data.get('username')
        password = request.data.get('password')

        # authenticate
        user = authenticate(username=username, password=password)

        if user:
            # Token을 가져오거나 생성
            token, __ = Token.objects.get_or_create(user=user)
            # Response에 돌려줄 데이터
            data = {
                "token": token.key,
            }
            return Response(data)

        # authenticate에 실패한 경우
        raise AuthenticationFailed('인증정보가 올바르지 않습니다.')
Beispiel #5
0
    def create(self, request, library_pk=None):
        user = request.user
        if user.is_anonymous():
            raise AuthenticationFailed('You need login to see you files')
        if library_pk is None:
            raise NotFound('Library not found')

        library = Library.objects.get(pk=library_pk)
        profile = user.profile
        uploaded_files = request.data.getlist('files')

        file_names = [f._name for f in uploaded_files]
        blobs = [f.read() for f in uploaded_files]
        # 以后要做客户端检测,通过客户端发送md5实现秒级上传
        file_hashes = [hashlib.md5(blob).hexdigest() for blob in blobs]
        res = []
        for file, file_hash, file_name in zip(uploaded_files, file_hashes,
                                              file_names):
            uploaded_path = os.path.join(settings.MEDIA_ROOT, file_hash)
            if os.path.exists(uploaded_path):
                #   TODO 检测是否已经上传
                paper_file = File.objects.get(hash=file_hash)
                if not library.has_file(paper_file):
                    library.add(paper_file)
                if not profile.is_owning(paper_file):
                    profile.own(paper_file)
            else:
                with open(uploaded_path, 'wb+') as destination:
                    for chunk in file.chunks():
                        destination.write(chunk)
                # TODO 这里有两个方法
                # 1, 通过celery来进行异步任务识别上传的文章
                # 2, 通过GET请求发送给识别服务器进行识别
                # paper = Paper.objects.get(pk=1)
                paper_file = File.objects.create(hash=file_hash,
                                                 name=file_name)
                library.add(paper_file)
                profile.own(paper_file)
            res.append(paper_file)
        # 利用celery 来识别文件
        pdf_read.delay(file_hashes)
        serializer = self.serializer_class(res, many=True)
        return Response(serializer.data, status=status.HTTP_201_CREATED)
Beispiel #6
0
    def get_object(self):
        requestAuthorId = self.kwargs['id']

        if not self.request.user.adminApproval:
            raise AuthenticationFailed(
                detail={"error": ["User has not been approved by admin"]})
        try: 
            authorExists = models.Followers.objects.filter(author=requestAuthorId).exists()
            if not authorExists:
                authorObj = models.Author.objects.get(id=requestAuthorId)
                models.Followers.objects.create(author=authorObj)
        except:
            raise ValidationError({"error": ["User not found"]})


        try:
            return models.Followers.objects.filter(author=requestAuthorId)
        except:
            raise ValidationError({"error": ["User not found"]})
Beispiel #7
0
    def authenticate(self, request: HttpRequest) -> Union[tuple, None]:
        """Used to authenticate the service request

        Args:
            request: The request object. Must contain a headers `dict`.

        Returns:
            The `user` and `auth` for the request. Or None if JWT was not used.
        """
        token = self._get_token(request)
        service_token = settings.JWT_AUTH['SERVICE_SECRET_TOKEN']

        if not token or not service_token:
            return None

        if token != service_token:
            raise AuthenticationFailed()

        return self._get_user(), token
Beispiel #8
0
    def post(self, request):

        username = request.data['username']
        password = request.data['password']
        user = authenticate(username=username, password=password)

        # 4. 얻어낸 User객체와 연결되는 Token을 get_or_create()로
        #    가져오거나 생성
        if user:
            token, _ = Token.objects.get_or_create(user=user)
        else:
            raise AuthenticationFailed()

        # 5. 생성된 Token의 'key'속성을 적절히 반환
        data = {
            'token': token.key,
            'user': UserSerializer(user).data,
        }
        return Response(data)
Beispiel #9
0
    def authenticate(self, validated_data):
        username = validated_data['username']
        access_token = validated_data['access_token']
        phone = get_validated_phone(access_token)
        new_password = validated_data['new_password']
        user_qs = User.objects.filter(username__exact=username)

        if len(user_qs) < 1:
            raise AuthenticationFailed(detail='Invalid credentials!')

        user = user_qs[0]

        if user.phone != phone:
            raise PermissionDenied(detail='Invalid Phone!')

        validate_password(new_password)
        user.set_password(new_password)
        user.save()
        return user
Beispiel #10
0
    def do_login(self, request, *args, **kwargs):

        u_user = request.data.get("u_user")

        u_password = request.data.get("u_password")

        user = userModel.get_user(u_user)

        if not user.check_password(u_password):

            raise AuthenticationFailed(detail="密码错误")

        token = generate_token()

        cache.set(token, user, timeout=USER_TOKEN_TIMEOUT)

        data = {"msg": "login success", "status": HTTP_200_OK, "token": token}

        return Response(data)
Beispiel #11
0
 def post(self, request):
     # 요청으로부터 username, password를 받음
     # 받은 내용으로 authenticate를 실행
     # - 인증 성공시
     #   인증된 User에 연결되는 Token을 가져오거나 생성(get_or_create)
     #   Token의 key값을 Response에 담아 돌려줌
     # - 인증 실패시
     #   AuthenticationFailed Exception을 raise
     username = request.data.get('username')
     password = request.data.get('password')
     user = authenticate(username=username, password=password)
     if user:
         # 인증에 성공하면 토큰을 생성하거나 가져와서 Response에 전달
         token, __ = Token.objects.get_or_create(user=user)
         data = {
             'token': token.key,
         }
         return Response(data)
     raise AuthenticationFailed()
Beispiel #12
0
    def post(self, request):
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)

        user = auth.authenticate(email=serializer.validated_data['email'],
                                 password=serializer.validated_data['password'])

        if user is None:
            raise AuthenticationFailed()

        if not Token.objects.filter(user=user).exists():
            token = Token.objects.create(user=user)
        else:
            token = Token.objects.get(user=user)

        token_serializer = TokenSerializer(data={'token': token.key})
        token_serializer.is_valid()

        return Response(data=token_serializer.data)
Beispiel #13
0
def register_social_user(provider, user_id, email, name):
    filtered_user_by_email = User.objects.filter(email=email)

    if filtered_user_by_email.exists():
        if provider == filtered_user_by_email[0].auth_provider:

            registered_user = authenticate(email=email,
                                           password=settings.SOCIAL_SECRET)

            return {
                'username': registered_user.username,
                'email': registered_user.email,
                'tokens': registered_user.tokens()
            }
        else:
            raise AuthenticationFailed(
                detail='Please continue your login using' +
                filtered_user_by_email[0].auth_provider)
    else:
        user = {
            'username': generate_username(name),
            'email': email,
            'password': settings.SOCIAL_SECRET
        }

        user = User.objects.create_user(**user)
        user.is_verified = True
        user.auth_provider = provider
        user.save()

        new_user = authenticate(email=email, password=settings.SOCIAL_SECRET)

        customer = {"user_id": user.id, "full_name": user.username}
        customer_serializer = CustomerSerializer(data=customer)
        customer_serializer.is_valid(raise_exception=True)
        customer_serializer.save()  #creates and save customer to db

        return {
            "email": new_user.email,
            "username": new_user.username,
            "tokens": new_user.tokens()
        }
Beispiel #14
0
    def validate(self, attrs):
        email = attrs.get("email")
        password = attrs.get("password")
        request = self.context.get("request")

        if email and password:
            try:
                user = authenticate(
                    request=self.context.get("request"), email=email, password=password
                )
            except AxesLockedOutException:
                # The user has been locked out after too many incorrect attempts
                raise CustomValidationError(error_key="login_incorrect_timeout")

            if not user or user.deleted_at:
                audit_log(audit_type=AUDIT_TYPE_LOGIN_FAILED, data={"email": email})
                raise CustomValidationError(error_key="wrong_email_password_combination")

            audit_log(audit_type=AUDIT_TYPE_LOGIN, user=user)
            # ensure the origin of the request is allowed for this user group
            env_key = request.META.get("HTTP_X_ORIGIN_ENVIRONMENT")
            if not user.has_groups(groups=ENVIRONMENT_GROUPS[env_key]):
                if not env_key:
                    logger.error(f"env_key not defined while logging {user.email}")
                else:
                    logger.error(
                        f"{user.email} does not have access to {ENVIRONMENT_GROUPS[env_key]}"
                    )
                raise CustomValidationError(error_key="invalid_access")

            email_verified = user.is_tra() or user.userprofile.email_verified_at
            if not email_verified:
                self.response_dict["needs_verify"] = True
            self.response_dict["token"] = str(user.get_access_token())

        else:
            raise AuthenticationFailed(
                _("Email and password are required to log in."), code="authorization"
            )

        attrs["user"] = user
        return attrs
Beispiel #15
0
    def authenticate_credentials(self, payload):
        """
        Return a user object to be associated with the present request, based on
        the content of an already-decoded / verified JWT payload.

        In the process of inflating the user object based on the payload, we also
        make sure that the roles associated with this user are up-to-date.
        """
        if 'preferred_username' not in payload:
            msg = 'Invalid JWT payload: preferred_username not present.'
            logger.warning(msg)
            raise AuthenticationFailed(msg)
        username = payload['preferred_username']

        # Even with MySQL set to use the READ COMMITTED isolation level, get_or_create sometimes
        # raises an IntegrityError and the object in question doesn't appear in a subsequent get()
        # call. Paired with non_atomic_requests, the retry logic here is meant to prevent IntegrityErrors
        # from causing authenticated requests to fail.
        retry = 0
        while True:
            # Exponential backoff. Keep sleep time short to prevent running out of available workers.
            countdown = 2**retry * COEFFICIENT

            try:
                logger.info(
                    'Attempting to get or create user [%s]. This is retry [%d].',
                    username, retry)
                user, __ = User.objects.get_or_create(username=username)  # pylint: disable=no-member
            except IntegrityError:
                retry += 1
                if retry <= MAX_RETRIES:
                    logger.warning(
                        'Failed to get or create [%s]. Sleeping for [%.2f] seconds.',
                        username, countdown)
                    time.sleep(countdown)
                else:
                    raise
            else:
                break

        _set_user_roles(user, payload)
        return user
Beispiel #16
0
def register_social_user(provider, user_id, email, name):
    filtered_user_by_email = User.objects.filter(email=email)
    if filtered_user_by_email.exists():
        if provider == filtered_user_by_email[0].auth_provider:
            registered_user = authenticate(
                username=filtered_user_by_email[0].username,
                password=os.getenv('SOCIAL_SECRET'))
            first_time = False
            temp = Profile.objects.get(owner=registered_user).name
            if temp is None:
                first_time = True
            return {
                'username': registered_user.username,
                'email': registered_user.email,
                'tokens': registered_user.tokens(),
                'first_time': first_time
            }

        else:
            raise AuthenticationFailed(
                detail='Please continue your login using ' +
                filtered_user_by_email[0].auth_provider)

    else:
        ele = generate_username(name)
        user = {
            'username': ele,
            'email': email,
            'password': os.getenv('SOCIAL_SECRET')
        }
        user = User.objects.create_user(**user)
        user.is_verified = True
        user.auth_provider = provider
        user.save()
        new_user = authenticate(username=ele,
                                password=os.getenv('SOCIAL_SECRET'))
        return {
            'email': new_user.email,
            'username': new_user.username,
            'tokens': new_user.tokens(),
            'first_time': True
        }
Beispiel #17
0
    def validate_auth_token(self, auth_token):
        user_data = google.Google.validate(auth_token)
        try:
            user_data['sub']
        except:
            raise serializers.ValidationError(
                'The token is invalid or expired. Please login again.'
            )

        if user_data['aud'] != config('GOOGLE_CLIENT_ID'):

            raise AuthenticationFailed('oops, who are you?')

        user_id = user_data['sub']
        email = user_data['email']
        name = user_data['name']
        provider = 'google'

        return register_social_user(
            provider=provider, user_id=user_id, email=email, name=name)
Beispiel #18
0
    def validate_claims(self, id_token):
        if isinstance(id_token.get('aud'), six.string_types):
            # Support for multiple audiences
            id_token['aud'] = [id_token['aud']]

        if id_token.get('iss') != self.issuer:
            msg = _('Invalid Authorization header. Invalid JWT issuer.')
            raise AuthenticationFailed(msg)
        if not any(aud in self.get_audiences(id_token)
                   for aud in id_token.get('aud', [])):
            msg = _('Invalid Authorization header. Invalid JWT audience.')
            raise AuthenticationFailed(msg)
        if settings.OIDC_AUTHORIZED_PARTY_CHECK:
            if len(id_token['aud']) > 1 and 'azp' not in id_token:
                msg = _(
                    'Invalid Authorization header. Missing JWT authorized party.'
                )
                raise AuthenticationFailed(msg)
            if 'azp' in id_token and id_token[
                    'azp'] not in setttings.OIDC_AUDIENCES:
                msg = _(
                    'Invalid Authorization header. Invalid JWT authorized party.'
                )
                raise AuthenticationFailed(msg)

        utc_timestamp = int(time.time())
        if utc_timestamp > id_token.get('exp', 0):
            msg = _('Invalid Authorization header. JWT has expired.')
            raise AuthenticationFailed(msg)
        if 'nbf' in id_token and utc_timestamp < id_token['nbf']:
            msg = _('Invalid Authorization header. JWT not yet valid.')
            raise AuthenticationFailed(msg)
        if 'iat' in id_token and utc_timestamp > id_token[
                'iat'] + setttings.OIDC_LEEWAY:
            msg = _('Invalid Authorization header. JWT too old.')
            raise AuthenticationFailed(msg)
        if setttings.OIDC_SCOPE not in id_token.get('scope'):
            msg = _('Invalid Authorization header.  Invalid JWT scope.')
            raise AuthenticationFailed(msg)
Beispiel #19
0
 def authenticate(
         cls, request: Union[HttpRequest,
                             Request]) -> Optional[Tuple[Any, None]]:
     personal_api_key_with_source = cls.find_key_with_source(request)
     if not personal_api_key_with_source:
         return None
     personal_api_key, source = personal_api_key_with_source
     PersonalAPIKey = apps.get_model(app_label="posthog",
                                     model_name="PersonalAPIKey")
     try:
         personal_api_key_object = (
             PersonalAPIKey.objects.select_related("user").filter(
                 user__is_active=True).get(value=personal_api_key))
     except PersonalAPIKey.DoesNotExist:
         raise AuthenticationFailed(
             detail=f"Personal API key found in request {source} is invalid."
         )
     personal_api_key_object.last_used_at = timezone.now()
     personal_api_key_object.save()
     return personal_api_key_object.user, None
    def authenticate_credentials(self, payload):
        """
        Return a user object to be associated with the present request, based on
        the content of an already-decoded / verified JWT payload.
        In the process of inflating the user object based on the payload, we also
        make sure that the roles associated with this user are up-to-date.
        """
        if 'preferred_username' not in payload:
            logger.warning(
                'Invalid JWT payload: preferred_username not present.')
            raise AuthenticationFailed()
        username = payload['preferred_username']
        user, __ = User.objects.get_or_create(username=username)  # pylint: disable=no-member
        admin_group = Group.objects.get(name=Role.ADMINS)  # pylint: disable=no-member
        if payload.get('administrator'):
            user.groups.add(admin_group)
        else:
            user.groups.remove(admin_group)

        return user
Beispiel #21
0
    def validate(self, attrs):
        user_data = Google.validate(attrs['abs_auth_uri'])
        try:
            user_data['sub']
        except Exception as e:
            raise serializers.ValidationError(
                'The token is invalid or expired. Please login again')

        if user_data['aud'] != settings.GOOGLE_CLIENT_ID:
            raise AuthenticationFailed('auth failed')

        user_id = user_data['sub']
        email = user_data['email']
        name = user_data['name']
        provider = 'google'

        return authenticate_social_user(provider=provider,
                                        user_id=user_id,
                                        email=email,
                                        name=name)
Beispiel #22
0
    def validate(self, attrs):
        try:
            password = attrs.get('password')
            token = attrs.get('token')
            uidb64 = attrs.get('uidb64')

            uid = force_str(urlsafe_base64_decode(uidb64))
            user = User.objects.get(pk=uid)

            if not PasswordResetTokenGenerator().check_token(user, token):
                raise AuthenticationFailed(
                    'The link is invalid,please request a new one', 401)

            user.set_password(password)
            user.save()
            return (user)
        except DjangoUnicodeDecodeError as identifier:
            raise serializers.ValidationError(
                ValidationError({'token': 'invalid token'}))
        return super().validate(attrs)
Beispiel #23
0
    def authenticate(self, request):
        auth = None
        user = AnonymousUser()
        allowed_agents = list(AuthorizedAgent.objects.filter(authorized=True).values_list("app_key", flat=True))
        agent = request.META.get("HTTP_ASSISTANT_AGENT")

        if agent in allowed_agents:
            auth = agent
        else:
            raise AuthenticationFailed(detail=API_AUTH_FAILED_RESPONSE_MESSAGE)

        try:
            remote = AuthorizedAgent.objects.get(authorized=True, app_key=agent)
        except AuthorizedAgent.DoesNotExist:
            remote = None

        if remote:
            user = remote.user

        return (user, auth)
Beispiel #24
0
    def get_queryset(self, **kwargs):
        if self.request.user.organization:
            address_id = self.request.query_params.get('id', None)
            keywords = self.request.query_params.get('searchValue', ''),
            keyword = ''.join(
                map(str, keywords)
            )  # Todo: crazy params parsed as tuple, add JSON.stringify() on ajax does not help, check if args[i] = JSON.stringify(loadOptions[i]) help

            if address_id:
                return Address.objects.filter(pk=address_id)
            else:
                return Address.objects.filter(
                    Q(street_number__icontains=keyword)
                    | Q(route__icontains=keyword)
                    | Q(raw__icontains=keyword))

        else:
            time.sleep(2)
            raise AuthenticationFailed(
                detail='Have your account assigned an organization?')
Beispiel #25
0
    def post(self, request, _format=None):

        email = request.data.get('email')
        password = request.data.get('password')

        user = self.get_user(email)
        if not user.check_password(password):
            raise AuthenticationFailed({'message': 'Invalid credentials'})

        payload = {
            'sub': user.id,
            'iat': datetime.datetime.utcnow(),
            'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=6)
        }

        token = jwt.encode(payload, settings.SECRET_KEY, algorithm='HS256')
        return Response({
            'token': token,
            'message': f'Welcome back {user.username}!'
        })
Beispiel #26
0
    def authenticate(self, request):
        jwt_value = self.get_jwt_value(request)
        if jwt_value is None:
            return None

        payload = self.decode_jwt(jwt_value)
        self.validate_claims(payload)

        user_resolver = self.settings.USER_RESOLVER  # Default: resolve_user
        user = user_resolver(request, payload)
        auth = UserAuthorization(user, payload, self.settings)

        if self.settings.REQUIRE_API_SCOPE_FOR_AUTHENTICATION:
            api_scope = self.settings.API_SCOPE_PREFIX
            if not auth.has_api_scope_with_prefix(api_scope):
                raise AuthenticationFailed(
                    _("Not authorized for API scope \"{api_scope}\"").format(
                        api_scope=api_scope))

        return (user, auth)
Beispiel #27
0
    def authenticate(self, request):
        jwt_value = self.get_jwt_value(request)
        if jwt_value is None:
            return None
        try:
            payload = self.decode_jwt(jwt_value)
        except:
            return None
        self.validate_claims(payload)
        user = get_or_create_user(payload, True)
        auth = UserAuthorization(user, payload, self.settings)

        if self.settings.REQUIRE_API_SCOPE_FOR_AUTHENTICATION:
            api_scope = self.settings.API_SCOPE_PREFIX
            if not auth.has_api_scope_with_prefix(api_scope):
                raise AuthenticationFailed(
                    _("Not authorized for API scope \"{api_scope}\"")
                    .format(api_scope=api_scope))
        user.amr = payload['amr']
        return (user, auth)
Beispiel #28
0
    def get_queryset(self):
        """
        :permission: this API is only for authenticated users (participants, coworker or organization).
                     Anonymous users should not get any info from this API.
        :query: Find all gatherings of all Attendances of the current user and their kid/care receiver, so all
                their "family" attendances gathering's characters (including not joined characters) will show up.
        :return:  all Characters of the logged in user and their kids/care receivers' gathering.
        """
        current_user = self.request.user
        current_user_organization = current_user.organization
        if current_user_organization:
            # user_assemblys = current_user.attendee.attendings.values_list('registration__assembly')
            # care_receiver_assemblys = current_user.attendee.related_ones.filter(to_attendee__relation__in=Attendee.BE_LISTED_KEYWORDS).values_list('attendings__registration__assembly')
            return CharacterService.by_family_meets_gathering_intervals(
                        user=current_user,
                    )

        else:
            time.sleep(2)
            raise AuthenticationFailed(detail='Have you registered any events of the organization?')
Beispiel #29
0
    def post(self, request, format=None):
        print(request.POST, request.data, request.data.get('username', False))
        if not request.data \
                or not request.data.get('username', False) \
                or not request.data.get('password', False):
            raise ParseError(detail="Please provide username/password")

        usecase = UserFactory.get_user_usecase()
        (session, error) = usecase.create_session(
            user_data={
                'username': request.data.get('username', False),
                'password': request.data.get('password', False)
            })
        print(error)
        if error == "notExist":
            raise AuthenticationFailed()

        session.token = session.token.decode()
        serialized_session = SessionSerializer(session)
        return Response(serialized_session.data)
Beispiel #30
0
    def login(self, request, user, data):

        if user.is_authenticated:
            return self._ok_response(user, request.META['CSRF_COOKIE'])
        if is_ratelimited(request, **self.ratelimit_config, increment=False):
            raise Ratelimited()

        username = input_to_username(data.get('username'))
        password = data.get('password')
        user = authenticate(request, username=username, password=password)

        if not user:
            is_ratelimited(request, **self.ratelimit_config, increment=True)
            logger.info({'event': 'login_failed', 'username': username})
            raise AuthenticationFailed()

        login(request, user)
        logger.info({'event': 'login_success', 'username': user.username})

        return self._ok_response(user, request.META['CSRF_COOKIE'])