Не передан идентификатор с uri что делать?

Описание ошибок протокола OAuth 2.0

В данном разделе приводится описание ошибок, возникающих при выполнении запросов в рамках протокола OAuth 2.0 и OpenId Connect 1.0.

В случае возникновения ошибок сервер возвращает информацию в двух полях:

  • error — код ошибки.
  • error_description — описание ошибки.

Далее будет представлена информация по кодам ошибок.

Ошибки конечной точки /authorize

invalid_request

В запросе не передан обязательный параметр, либо значения переданного параметра некорректно, либо параметр пристутствует в запросе несколько раз, либо весь запрос имеет неправильный формат.

Возможные причины

  • Осутствие обязательных парамтеров в запросе ( client_id , redirect_uri , resource , response_type ).
  • Переданы некорректные значения параметров (неправильный формат redirect_uri , resource ).
  • Переданы незарегистрированные значения параметров (незарегистрированный resource ).
  • Переданы неподдерживаемые значения параметров (неподдерживаемый response_mode ).
  • Передано некорректное значение параметра id_token_hint .
  • Маркер, указанный в значении параметра id_token_hint , невалиден.
  • Сервер не настроен на обработку параметра id_token_hint .

unauthorized_client

Клиент с указанным в запросе идентификатором не зарегистрирован, отключён, либо клиенту запрещено получения маркера доступа в рамках данного сценария.

Возможные причины

  • По переданному в запросе client_id не найдено зарегистрированных клиентов.
  • Переданный в запросе client_id принадлежит заблокированному клиенту.
  • Использованный в запросе redirect_uri не зарегистрирован для используемого клиента.
  • Используемый сценарий не разрешён для используемого клиента.

unsupported_response_tpe

Тип ответа не поддерживается.

Указанный в запросе response_type не поддерживается.

Возможные причины

  • В запросе указан параметр response_type со значениями отличными от
    • code ,
    • token ,
    • id_token ,
    • id_token token ,
    • code id_token
    • code token
    • code id_token token .

invalid_scope

Неправильная область использования.

Указанный в запросе scope не зарегистрирован на сервере.

Возможные причины

  • В запросе указан параметр scope , значение которого не зарегистрировано на сервере.
  • В запросе указан параметр scope , заблокированный на сервере.
  • Срели значений параметра scope указано больше одной области использования, требующей подтверждения.
  • Переданные парамтеры dss_scope_params имеют неправильный формат.

login_required

Запрос не может быть выполнен в интерактивном режиме (с указанием параметра prompt со значением none ).

Возможные причины

  • Запрос не может быть выполнен в неинтерактивном режиме, так как требуется аутентификация пользователя.

Ошибки конечной точки /token

invalid_request

В запросе не передан обязательный параметр, либо значения переданного параметра некорректно, либо параметр пристутствует в запросе несколько раз, либо весь запрос имеет неправильный формат.

Возможные причины

  • Не удалось получить идентификатор клиента из запроса.
  • Отсутствие обязательных параметров в запросе (для сценария обмена маркеров: subject_token , actor_token_type , resource , grant_type , refresh_token ).
  • Переданы некорректные значения параметров ( resource ).
  • Переданы незарегистрированные значения параметров (незарегистрированный resource ).
  • Переданы некорректные значения парaметров (для сценария обмена маркеров: неправильный формат subject_token , actor_token ).
  • Маркеры доступа, указанные в значениях параметров subject_token , actor_token , не действительны.
  • Переданы неподдерживаемые значения параметров (для сценария обмена маркеров: неподдерживаемый тип subject_token_type , subject_token_type ).
  • Сервер не настроен на поддержку сценария обмена маркеров.

invalid_client

Не удалось осуществить аутентификацию клиента.

Возможные причины

  • Не удалось получить идентификатор клиента из запроса.
  • Клиент с указанным в запросе идентификатором не зарегистрирован или отключён.

invalid_grant

Разрешение, используемое клиентом, не является действительным.

Возможные причины

  • Не передан параметр password в сценарии с использованием учётных данных владельца ресурсов.
  • Сервер не настроен на обработку сценария с использованием учётных данных владельца ресурсов.
  • Не удалось аутентифицировать пользователя по переданным username и password .
  • Сценарий с использованием учётных данных владельца ресурсов не может быть использован для данной учётной записи пользователя из-за включенной вторичной аутентификации.
  • Не передан код авторизации в сценарии с кодом авторизации.
  • Переданный код авторизации истёк или не действителен.
  • Переданный код авторизации был получен другим клиентом.

unauthorized_client

Клиент с указанным в запросе идентификатором не зарегистрирован, отключён, либо переданы неверные учётные данные клиента.

Возможные причины

  • Используется тип учётных данных клиента, отличный от разделяемого секрета.
  • Переданы неверные учётные данные.
  • Переданные учётные данные клиента истекли.

usupported_grant_type

Неподдерживаемый тип разрешение.

Разрешение, используемое клиентом, не поддерживается сервером.

Возможные причины

  • Передан тип разрешения отличный от
    • code ,
    • password ,
    • urn:ietf:params:oauth:grant-type:token-exchange ,
    • refresh_token .

Универсальный идентификатор ресурсов URI

URI (Uniform Resource Identifier, Универсальный идентификатор ресурса) – компактная строка символов для идентификации абстрактного или физического ресурса. Под ресурсом понимается любой объект, принадлежащий некоторому пространству. Необходимость в URI была понятна разработчикам WWW c момента зарождения системы, т.к. предполагалось объединение в единую информационную среду средств, использующих различные способы идентификации информационных ресурсов. Была разработана спецификация, которая включала в себя обращения к FTP, Gopher, WAIS, Usenet, E–mail, Prospero, Telnet, X.500 и, конечно, HTTP (WWW). В итоге была разработана универсальная спецификация, которая позволяет расширять список адресуемых ресурсов за счет появления новых схем.

Появление URN связано с желанием адресовать части почтового сообщения MIME. Принципы построения адреса WWW. В основу URI были заложены следующие принципы:

· Расширяемость – новые адресные схемы должны легко вписываться в существующий синтаксис URI.

· Полнота – по возможности, любая из существовавших схем должна описываться посредством URI.

· Читаемость – адрес должен был быть легко читаем пользователем, что вообще характерно для технологии WWW – документы вместе с ссылками могут разрабатываться в обычном текстовом редакторе.

Прежде, чем рассмотреть различные схемы представления адресов приведем пример простого адреса URI:

Перед двоеточием стоит идентификатор схемы адреса – «http». Это имя отделено двоеточием от остатка URI, который называется «путь». В данном случае путь состоит из доменного адреса машины, на которой установлен сервер HTTP и пути от корня дерева сервера к файлу «index.html». Кроме представленной выше полной записи URI, существует упрощенная. Она предполагает, что к моменту ее использования многие параметры адреса ресурса уже определены (протокол, адрес машины в сети, некоторые элементы пути). При таких предположениях автор гипертекстовых страниц может указывать только относительный адрес ресурса, т.е. адрес относительно определенных базовых ресурсов.

URL (Uniform Resource Locator, Универсальный указатель ресурса), –подмножество схем URI, который идентифицирует ресурс по способу доступа к нему (например, его «местонахождению в сети») вместо того, чтобы идентифицировать его по названию или другим атрибутам этого ресурса. URL явно описывает, как добраться до объекта.

Синтаксис: : , где:

scheme = «http» | «ftp» | «gopher» | «mailto» | «news» | «telnet» | «file» | «man» | «info» | «whatis» | «ldap» | «wais» | . – имя схемы

scheme–specific–part – зависит от схемы. В scheme–specific–part можно использовать шестнадцатеричные значения в виде: %5f. Обязательно должны кодироваться непечатные октеты: 00–1F, 7F, 80–FF.

URN (Uniform Resource Name, Универсальное имя ресурса) – частная URI–схема «urn:» с подмножеством «пространства имен», который должен быть уникальным и неизменным даже в том случае, когда ресурс уже не существует или недоступен.

Предполагается что, например браузер, знает, где искать этот ресурс.

Синтаксис: urn: namespace: data1.data2,more–data, где namespace (пространство имен) определяет, каким образом используются данные, указанные после второго «:».

urn: ISBN: 0–395–36341–6

ISBN – тематический классификатор для издательств,

0–395–36341–6 – конкретный номер тематики книги или журнала

При получении URN клиентская программа обращается к ISBN (каталогу «тематический классификатор для издательств» в Интернете). И получает расшифровку номера тематики «0–395–36341–6» (например: «квантовая химия»). URN принят сравнительно недавно, в текущие версии HTML не включен и службы каталогов пока не развиты, поэтому URN не так широко распространен как URL.

Схемы адресации ресурсов Internet

Существует 3 схемы адресации ресурсов Internet. В схеме указывается ее идентификатор, адрес машины, TCP–порт, путь в директории сервера, переменные и их значения, метка.

Схема HTTP. Это основная схема для WWW. В схеме указывается ее идентификатор, адрес машины, TCP–порт, путь в директории сервера, поисковый критерий и метка.

Синтаксис: http://[ [:

http – название схемы

user – имя пользователя

password – пароль пользователя

host – имя хоста

port – номер порта

url–path – путь к файлу и сам файл

По умолчанию, port=80.

Приведем несколько примеров URI для схемы HTTP:

Это наиболее распространенный вид URI, применяемый в документах WWW. Вслед за именем схемы (http) следует путь, состоящий из доменного адреса машины и полного адреса HTML–документа в дереве сервера HTTP.

В качестве адреса машины допустимо использование и IP–адреса:

Если сервер протокола HTTP запущен на другой, отличный от 80 порт TCP, то это отражается в адресе:

При указании адреса ресурса возможна ссылка на точку внутри файла HTML. Для этого вслед за именем документа может быть указана метка внутри документа:

Схема FTP. Данная схема позволяет адресовать файловые архивы FTP из программ–клиентов World Wide Web. При этом программа должна поддерживать протокол FTP. В данной схеме возможно указание не только имени схемы, адреса FTP–архива, но и идентификатора пользователя и даже его пароля.

Синтаксис: ftp://[ [:

ftp – название схемы

user – имя пользователя

password – пароль пользователя

host – имя хоста

port – номер порта

url–path – путь к файлу и сам файл

По умолчанию, port=21, user=anonymous, password=email–адрес.

Наиболее часто данная схема используется для доступа к публичным архивам FTP:

В данном случае записана ссылка на архив «polyn.net.kiae.su» c идентификатором «anonymous» или «ftp» (анонимный доступ). Если есть необходимость указать идентификатор пользователя и его пароль, то можно это сделать перед адресом машины:

В данном случае эти параметры отделены от адреса машины символом «@», а друг от друга двоеточием.

Схема TELNET. По этой схеме осуществляется доступ к ресурсу в режиме удаленного терминала. Обычно клиент вызывает дополнительную программу для работы по протоколу telnet. При использовании этой схемы необходимо указывать идентификатор пользователя, допускается использование пароля.

Синтаксис: telnet://[ [:

telnet – название схемы

user – имя пользователя

password – пароль пользователя

host – имя хоста

port – номер порта

По умолчанию, port=23.

Реально, доступ осуществляется к публичным ресурсам, и идентификатор и пароль являются общеизвестными, например, их можно узнать в базах данных Hytelnet.

Из приведенных выше примеров видно, что спецификация адресов ресурсов URI является довольно общей и позволяет проидентифицировать практически любой ресурс Internet. При этом число ресурсов может расширяться за счет создания новых схем.

Служба WWW

Служба WWW (World Wide Web) – предназначена для обмена гипертекстовой информацией, построена по схеме «клиент–сервер». Браузер (Internet Explorer, Opera . ) является мультипротокольным клиентом и интерпретатором HTML. И как типичный интерпретатор, клиент в зависимости от команд (тегов) выполняет различные функции. В круг этих функций входит не только размещение текста на экране, но обмен информацией с сервером по мере анализа полученного HTML–текста, что наиболее наглядно происходит при отображении встроенных в текст графических образов.

Сервер HTTP (Apаche, IIS . ) обрабатывает запросы клиента на получение файла. В начале служба WWW базировалась на трех стандартах:

· HTML (HyperText Markup Lan–guage) – язык гипертекстовой разметки документов;

· URL (Universal Resource Locator) – универсальный способ адресации ресурсов в сети;

· HTTP (HyperText Transfer Protocol) – протокол обмена гипертекстовой информацией.

Позже добавили CGI (Common Gateway Interface) – универсальный интерфейс шлюзов. Создан для взаимодействия HTTP – сервера с другими программами установленными на сервере (например, СУБД).

Схема работы WWW сервера

WWW сервер – это такая часть глобальной или внутрикорпоративной сети, которая дает возможность пользователям сети получать доступ к гипертекстовым документам, расположенным на данном сервере. Для взаимодействия с WWW сервером пользователь сети должен использовать специализированное программное обеспечение – браузер (от англ. browser) –программа просмотра.

Рассмотрим более схему работы WWW–сервера:

1. Пользователь сети запускает браузер, в функции которого входит:

· установление связи с сервером;

· получение требуемого документа;

· отображение полученного документа;

· реагирование на действия пользователя – доступ к новому документу. После запуска браузер по команде пользователя или автоматически устанавливает связь с заданным WWW – сервером и передает ему запрос-получение заданного документа.

2. WWW сервер ищет запрашиваемый документ и возвращает результаты браузеру.

3. Браузер, получив документ, отображает его пользователю и ожидает его реакции. Возможные варианты:

· ввод адреса нового документа;

· печать, поиск, другие операции над текущим документом;

· активизация (нажатие) специальных зон полученного документа, называемых связями (link) и ассоциированными с адресом нового документа. В первом и третьем случае происходит обращение за новым документом.

Не передан идентификатор с uri что делать?

Для использования клиентской OAuth-авторизации необходимо включить в настройках приложения клиентскую авторизацию.

Во время создания приложения требуется указать redirect_uri, который будет использован во время авторизации OAuth:

Тип Описание Пример
Android SDK okauth://ok
вместо [app_id] необходимо подставить id приложения
okauth://ok123456
iOS SDK ok://authorize
вместо [app_id] необходимо подставить id приложения
ok123456://authorize
External URI, который будет обрабатывать авторизацию.
Можно использовать https://oauth.mycdn.me/blank.html
http://localhost/auth

1. Открытие диалога авторизации OAuth

Во время создания приложения потребуется указать redirect_uri, который будет использован во время авторизации OAuth

Для начала процесса авторизации нужно открыть новое окно браузера (или webView) и осуществить переход на специально сформированный URL:

https://connect.ok.ru/oauth/authorize?client_id=&scope=&response_type=<>&redirect_uri=&layout=&state=

Название Обязательный Описание
client_id Да Идентификатор приложения
scope Да Запрашиваемые права приложения, разделённые символом ‘;’. См. права приложения
response_type Да Тип ответа от сервера, укажите token
redirect_uri Да URI, на который будет передан access_token. URI должен посимвольно совпадать с одним из URI, зарегистрированных в настройках приложения.
Часть URI после символа ‘?’ (query) не учитывается при проверке, тем не менее, для передачи динамически изменяющихся данных рекомендуется использовать параметр state.
layout Нет Внешний вид окна авторизации:
* w – (по умолчанию) стандартное окно для полной версии сайта;
* m – окно для мобильной авторизации;
* a – упрощённое окно для мобильной авторизации без шапки.
state Нет Параметр состояния. В неизменном виде пробрасывается в redirect_uri. Позволяет передавать произвольные данные между разными фазами OAuth и защищаться от xsrf.

2. Разрешение прав доступа

Если пользователь ранее выдал приложению все права, указанные в параметре scope, то окно автоматически закрывается и дополнительное подтверждение от пользователя не требуется.

После перехода по сформированному URL пользователь будет должен ввести свой логин и пароль, если ранее он этого не сделал. После входа на сайт ему будет предложено авторизовать приложение и подтвердить запрошенные права:

3. Получение access_token

После подтверждения авторизации пользователь будет перенаправлен на указанный при открытии диалога авторизации redirect_uri, в котором после символа решётки будут переданы параметры access_token и session_secret_key, а также state в случае, если он был указан на этапе 1:

#access_token=&session_secret_key=&state=&permissions_granted=&expires_in=

Название Описание
access_token Токен доступа, используемый для формирования запроса к API
session_secret_key Секретный сессионный ключ, используемый для подписи запроса к API
state Значение, которое было передано в параметре state при открытии диалога авторизации
permissions_granted Права, выданные пользователем приложению
expires_in Время действия токена доступа в секундах

В случае ошибки или отказа от авторизации будет передан параметр error, идентифицирующий причину проблемы:

#error=&state=

Авторизация Google OAuth 2 — ошибка: redirect_uri_mismatch

На веб-сайте https://code.google.com/apis/console я зарегистрировал свое приложение, настроил сгенерированный идентификатор клиента: и Client Secret для своего приложения и попытался войти в систему с помощью Google. К сожалению, я получил сообщение об ошибке:

Что означает это сообщение, и как я могу это исправить? Я использую драгоценный камень omniauth-google-oauth2 .

URI перенаправления (куда возвращается ответ) должен быть зарегистрирован в консоли API, и ошибка указывает на то, что вы этого не сделали или сделали не правильно.

Перейдите в консоль для вашего проекта и посмотрите под API Access. Вы должны увидеть свои client ID & client secret там, вместе со списком URI перенаправления. Если требуемый URI отсутствует в списке, нажмите «Изменить настройки» и добавьте URI в список.

РЕДАКТИРОВАТЬ: (Из комментария с высокой оценкой ниже) Обратите внимание, что обновление консоли API Google и это изменение может занять некоторое время. Обычно всего несколько минут, но иногда кажется, что это дольше.

В моем случае это был www и non-www URL. Фактический сайт имел www URL, а URL авторизованного перенаправления в консоли разработчика Google имели non-www URL. Следовательно, произошло несоответствие в URI перенаправления. Я решил это путем обновления Authorized Redirect URIs в консоли разработчика Google до www URL.

Другие распространенные несоответствия URI:

  • Использование http:// в URI авторизованного перенаправления и в https:// качестве фактического URL-адреса, или наоборот
  • Использование конечной косой черты ( http://example.com/ ) в URI авторизованного перенаправления и отсутствие конечной косой черты ( http://example.com ) в качестве фактического URL-адреса или наоборот

Вот пошаговые снимки экрана консоли разработчика Google, чтобы тем, кому трудно найти страницу консоли разработчика, чтобы обновить URI перенаправления.

Выберите свой проект

  1. Нажмите на Credentials меню. И под OAuth 2.0 Client IDs , вы найдете свое имя клиента. В моем случае это так Web Client 1 . Нажмите на него, и появится всплывающее окно, где вы можете редактировать авторизованныйURI-адрес Javascript и авторизованный URI перенаправления .

Если вы используете кнопку JavaScript javascript , вам придется использовать postmessage вместо фактического URI. Мне потребовался почти весь день, чтобы понять это, поскольку в документах Google по какой-то причине не указано четко.

В любом потоке, в котором вы получили код авторизации на стороне клиента, например, GoogleAuth.grantOfflineAccess() API , и теперь вы хотите передать код на сервер, выкупить его, сохранить токены доступа и обновить, тогда вам придется использовать буквенную строку postmessage вместо redirect_uri.

Например, на основе фрагмента в документе Ruby :

Единственная документация Google, которую можно упомянуть, postmessage — это старый документ для входа в Google+ . Вот скриншот и ссылка на архив, так как G + закрывается, и эта ссылка, вероятно, исчезнет:

Абсолютно непростительно, что страница документации для автономного доступа не упоминает об этом. #FacePalm

Для моего веб-приложения я исправил свою ошибку, написав

Обязательно проверьте протокол «http: //» или «https: //», так как Google также проверяет протокол. Лучше добавить оба URL в список.

Это кажется довольно странным и раздражающим, что единого решения не существует. для меня http: // localhost: 8000 не сработало, но http: // localhost: 8000 / сработало.

Когда вы регистрируете свое приложение на https://code.google.com/apis/console и создаете идентификатор клиента, вы получаете возможность указать один или несколько URI перенаправления. Значение redirect_uri параметра в вашем URI аутентификации должно точно соответствовать одному из них.

Этот ответ так же , как ответить на этот вопрос Майка , и ответ Джеффа , оба набора redirect_uri на postmessage на стороне клиента. Я хочу добавить больше о стороне сервера, а также об особых обстоятельствах, применимых к этой конфигурации.

Tech Stack

Backend

  • Python 3.6
  • Джанго 1.11
  • Django REST Framework 3.9 : сервер как API, не рендеринг шаблона, не так уж много другого.
  • Django REST Framework JWT 1.11
  • Django REST Social Auth create-react-app версия 2.1.5
  • response-google-login : 5.0.2

Поток «Код» (специально для Google OAuth2)

Описание: React -> запросить «код» социальной авторизации -> запросить токен jwt для получения статуса «логин» с точки зрения вашего собственного внутреннего сервера / базы данных.

  1. Frontend (React) использует «кнопку входа Google», responseType=»code» чтобы получить код авторизации. (это не токен, не токен доступа!)
    • Кнопка входа в Google из react-google-login вышеупомянутых.
    • Нажатие на кнопку откроет всплывающее окно для пользователя, чтобы выбрать учетную запись. После того как пользователь выберет один и окно закроется, вы получите код из функции обратного вызова кнопки.
  2. Интерфейс отправляет это на конечную точку JWT внутреннего сервера.
    • POST запрос, с
  3. Для моего сервера Django я использую Django REST Framework JWT + Django REST Social Auth. Django получает код от внешнего интерфейса, проверьте его с помощью сервиса Google (сделано для вас). После проверки он отправит JWT (токен) обратно во внешний интерфейс. Теперь интерфейс может собрать токен и хранить его где-нибудь.
    • Все REST_SOCIAL_OAUTH_ABSOLUTE_REDIRECT_URI , REST_SOCIAL_DOMAIN_FROM_ORIGIN и REST_SOCIAL_OAUTH_REDIRECT_URI в Джанго, settings.py не нужны . (Это константы, используемые Django REST Social Auth) Короче говоря, вам не нужно ничего настраивать, связанные с перенаправлением URL в Django . «redirect_uri»: «postmessage» В React внешнего интерфейса достаточно. Это имеет смысл, потому что социальная работа по аутентификации, которую вы должны выполнить на своей стороне, — это все POST-запросы в стиле Ajax во внешнем интерфейсе, без отправки какой-либо формы, поэтому по умолчанию перенаправление не происходит. Вот почему URL-адрес перенаправления становится бесполезным, если вы используете поток кода + JWT, а настройка URL-адреса перенаправления на стороне сервера не дает никакого эффекта.
  4. Django REST Social Auth управляет созданием аккаунта. Это означает, что он проверит адрес электронной почты / фамилию учетной записи Google и выяснит, соответствует ли она какой-либо учетной записи в базе данных. Если нет, он создаст его для вас, используя точную электронную почту и фамилию. Но имя пользователя будет примерно таким, как youremailprefix717e248c5b924d60 если бы ваш адрес электронной почты был youremailprefix@example.com . Он добавляет некоторую случайную строку для создания уникального имени пользователя. Это поведение по умолчанию, я считаю, что вы можете настроить его и свободно копаться в их документации.
  5. Внешний интерфейс хранит этот токен, и когда он должен выполнить CRUD для внутреннего сервера, особенно создать / удалить / обновить, если вы прикрепите токен в свой Authorization заголовок и отправите запрос к внутреннему интерфейсу, серверный интерфейс Django теперь распознает его как имя входа, то есть аутентифицированное пользователь. Конечно, если ваш токен истекает, вы должны обновить его, сделав еще один запрос.

О, боже мой, я потратил более 6 часов и наконец понял это правильно! Я считаю, что это первый раз, когда я увидел эту postmessage вещь. Любой, кто работает над Django + DRF + JWT + Social Auth + React комбинацией, обязательно столкнется с этим. Я не могу поверить, что ни одна из статей там не упоминает об этом, кроме ответов здесь. Но я очень надеюсь, что этот пост сэкономит вам массу времени, если вы используете стек Django + React.

Что такое ошибка «необъявленный идентификатор» и как ее исправить?

Что такое необъявленные ошибки идентификатора? Каковы общие причины и как их исправить?

Пример текстов ошибок:

  • Для компилятора Visual Studio: error C2065: ‘cout’ : undeclared identifier
  • Для компилятора GCC: ‘cout’ undeclared (first use in this function)

Решение

Чаще всего они приходят из-за того, что забывают включить заголовочный файл, содержащий объявление функции, например, эта программа выдаст ошибку «необъявленный идентификатор»:

Отсутствует заголовок

Чтобы это исправить, мы должны включить заголовок:

Если вы написали заголовок и включили его правильно, заголовок может содержать неправильный включить охрану .

Переменная с ошибкой

Другой распространенный источник ошибки новичка возникает, когда вы неправильно написали переменную:

Неправильный объем

Например, этот код выдаст ошибку, потому что вам нужно использовать std::string :

Использовать до объявления

g не был объявлен до его первого использования. Чтобы это исправить, либо переместите определение g до f :

Или добавить декларацию g до f :

stdafx.h не сверху (специфично для VS)

Это зависит от Visual Studio. В VS нужно добавить #include «stdafx.h» перед любым кодом. Код до того, как он игнорируется компилятором, так что если у вас есть это:

#include будет проигнорировано Вам нужно переместить его ниже:

Не стесняйтесь редактировать этот ответ.

Другие решения

Рассмотрим похожую ситуацию в разговоре. Представьте, что ваш друг говорит вам: «Боб идет на ужин», а ты не представляешь, кто такой Боб. Вы будете в замешательстве, верно? Твой друг должен был сказать: «У меня есть коллега по работе по имени Боб. Боб подходит к обеду». Теперь Боб объявлен, и вы знаете, о ком говорит ваш друг.

Компилятор выдает ошибку «необъявленный идентификатор», когда вы пытаетесь использовать какой-то идентификатор (который будет именем функции, переменной, класса и т. Д.), И компилятор не видит объявления для него. То есть компилятор понятия не имеет, о чем вы говорите, потому что раньше его не видел.

Если вы получаете такую ​​ошибку в C или C ++, это означает, что вы не сказали компилятору о том, что вы пытаетесь использовать. Объявления часто встречаются в заголовочных файлах, поэтому, скорее всего, это означает, что вы не включили соответствующий заголовок. Конечно, может случиться так, что вы просто не помните, чтобы объявить сущность вообще.

Некоторые компиляторы выдают более конкретные ошибки в зависимости от контекста. Например, пытаясь скомпилировать X x; где тип X не был объявлен с Clang скажет вам «неизвестное имя типа X «. Это гораздо полезнее, потому что вы знаете, что он пытается интерпретировать X как тип. Тем не менее, если у вас есть int x = y; , где y еще не объявлено, он скажет вам «использование необъявленного идентификатора y «потому что есть некоторая двусмысленность в том, что именно y может представлять.

У меня была такая же проблема с пользовательским классом, который был определен в пространстве имен. Я пытался использовать класс без пространства имен, вызывая ошибку компилятора «идентификатор» MyClass «не определен».
Добавление

или используя класс, как

В C и C ++ все имена должны быть объявлены перед использованием. Если вы попытаетесь использовать имя переменной или функции, которая не была объявлена, вы получите ошибку «необъявленный идентификатор».

Однако функции — это особый случай в C (и только в C), в котором вам не нужно сначала объявлять их. Компилятор C будет предполагать, что функция существует с числом и типом аргументов, как в вызове. Если фактическое определение функции не совпадает, вы получите еще одну ошибку. Этот особый случай для функций не существует в C ++.

Вы исправляете ошибки такого рода, проверяя, что функции и переменные объявлены до их использования. В случае printf вам нужно включить заголовочный файл (или же в C ++).

Для стандартных функций я рекомендую вам проверить, например, этот справочный сайт , и найдите функции, которые вы хотите использовать. Документация для каждой функции говорит вам, какой заголовочный файл вам нужен.

Эти сообщения об ошибках

означает, что вы используете имя printf но компилятор не видит, где было объявлено имя, и, соответственно, не знает, что это значит.

Любое имя, используемое в программе, должно быть объявлено до ее использования. Компилятор должен знать, что обозначает имя.

В этом конкретном случае компилятор не видит объявление имени printf , Как мы знаем (но не компилятор) это имя стандартной функции C, объявленной в заголовке в C или в заголовке в C ++ и размещены в стандарте ( std:: ) и глобальный ( :: ) (не обязательно) пространства имен.

Поэтому, прежде чем использовать эту функцию, мы должны предоставить объявление ее имени компилятору путем включения соответствующих заголовков.

Например
C:

C ++:

Иногда причиной такой ошибки является простая опечатка. Например, давайте предположим, что вы определили функцию PrintHello

но в основном вы сделали опечатку и вместо PrintHello ты напечатал printHello с строчной буквы «р».

В этом случае компилятор выдаст такую ​​ошибку, потому что он не видит объявление имени printHello , PrintHello а также printHello два разных имени, одно из которых было объявлено, а другое не объявлено, но используется в теле основного

Другая возможная ситуация: доступ к родительскому элементу (классу шаблона) в классе шаблона.

Исправить метод: использование родительского члена класса по его полному имени (с помощью префикса this-> или же parentClassName:: на имя члена).

Это похоже на использование функции без ее объявления. заголовочный файл будет содержать
функция printf (). Включите заголовочный файл в вашу программу, это решение для этого.
Некоторые пользовательские функции могут также вызывать ошибки, если они не были объявлены перед использованием. Если
это используется во всем мире без проб.

В большинстве случаев, если вы уверены, что импортировали данную библиотеку, Visual Studio поможет вам с IntelliSense.