2012-05-24 3 views
8

У меня есть холст приложение Facebook. Я использую JS SDK для аутентификации пользователя на стороне браузера и запроса различной информации через FB.api (например, имя, друзья и т. Д.).Как пройти Facebook Id от клиента к серверу надежно

Я также хочу упорствовать дополнительную информацию о пользователе (не дотянул Facebook) в базу данных на моем сервере, сделав Ajax вызов:

{ userFavouriteColour: "Red" } 

Чтобы сохранить это на сервере и ассоциированной с правильным пользователем , Мне нужно знать UID Facebook, и это создает проблему. Как передать uid с клиента на сервер.

Вариант 1: Добавить идентификатор пользователя для запроса Ajax:

{ uid: "1234567890", 
    userFavouriteColour: "Red" } 

Это, очевидно, не хорошо. Было бы тривиально, если бы кто-нибудь сделал запрос ajax на мой веб-сервис, используя чужой Facebook Id и изменил их любимый цвет.

Вариант 2: На сервере извлеките uid из файла cookie: Возможно ли это? Я прочитал, что Facebook устанавливает cookie, содержащий идентификатор доступа и доступа, но у меня есть доступ к этому файлу cookie в моем домене? Что еще более важно, я могу надежно экстракт Uid образует печенье или это открыто для подмены так же, как вариант 1.

Вариант 3: Пользователь стороны сервера аутентификация на сервере: я мог бы использовать поддерживаемый сервер для проверки подлинности пользователя на моем сервере. Но будет ли это работать, если я уже использую аутентификацию на стороне клиента в браузере? У меня будет два разных токена доступа? Я хотел бы сделать запросы FB.api из браузера, поэтому мне нужен токен доступа на клиенте (а не только на сервере).

Это должно быть очень распространенным сценарием, так что я думаю, что я что-то фундаментальное отсутствует. Я прочитал много документации Facebook (различных потоков аутентификации маркеров доступа, signed_request и т.д.) и многих постов на SO, но я до сих пор не понимаю, как на стороне клиента аутентификации и на стороне сервера игры аутентификации хорошо вместе.

Короче говоря, я хочу знать личность пользователя на сервере, но все же делать запросы к api-mail Facebook из клиентского браузера?

(я использую ASP.NET и # SDK Facebook C на сервере)

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

ответ

3

Вариант 1: Самый простой способ, которым я могу думать о том, чтобы включить в JS маркер доступа и передать его с вызовом AJAX.

Вариант 2: Используя такой же, как вариант 1, но вместо того, чтобы посылать только маркер доступа, отправьте signedRequest.

На стороне сервера вы можете декодировать его с помощью (TryParseSignedRequest) метод, который даст вам UserID :-)

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

Отказ от ответственности:

У меня нет никакого опыта кодирования в C#, но немного поиск в Google дал мне это:

Facebook C# SDK for ASP.NET

Making AJAX Requests with the Facebook C# SDK

+0

Если я передаю accessToken через ajax, есть ли способ извлечь Facebook userId из токена на моем сервере без запроса в Facebook? И это безопасно для подмены? Я не хочу делать запрос FB api с моего сервера, поэтому я хочу извлечь Id пользователя на основе информации, переданной клиентом. – njr101

+0

хорошо, FB.getLoginStatus (https://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus/) в Javacript возвращает больше токена доступа, но также идентификатор пользователя, поэтому вы можете отправить его на сервер side ... – Roni

+0

Спасибо за ссылку - это объясняет, как получить userId на клиенте. Возможно, я не очень ясно объясняю себя. Если я передам этот userId на мой сервер, тогда он будет открыт для подмены. Как я могу получить userId на сервере безопасным образом? – njr101

0

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

Вы можете работать на вариант 2, но да, это будет также подвержен подделке.

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

+0

Означает ли это, что у меня было бы два разных токена доступа, один для запросов от клиента и один для запросов с сервера? Или два токена доступа будут одинаковыми? – njr101

+0

у вас будет тот же токен доступа. –

0

У меня был точно такой же вопрос в последнее время. Это вариант 2. Проверьте this post из блога Facebook.

Чтобы быть честным, мне недостаточно хакера, чтобы узнать, можете ли вы обмануть UID в файле cookie, но это, по-видимому, является «официальным» способом сделать это.

EDIT: к другому вопросу по варианту 2, да, я считаю, что вам нужно получить доступ к этому файлу cookie в вашем домене.

+0

Спасибо за подсказку, но как я могу извлечь userId? Я предполагаю, что мне нужно извлечь его из accessToken, поскольку он зашифрован. В примере в ссылке используется PHP SDK. Поскольку это возможно в PHP, тогда я думаю, что информация хранится в accessToken, но я не могу найти нигде, что объясняет, как извлечь ее, используя C# SDK (или даже вручную) – njr101

+0

Я не знаком с C# SDK, но вы можете посмотреть, как работает PHP sdk, посмотрев на источник [здесь] (https://github.com/facebook/php-sdk/blob/master/src/base_facebook.php), найдите 'getUserFromAvailableData' на страница. Вы должны получить ['signed_request'] (http://developers.facebook.com/docs/authentication/signed_request/) и декодировать его, используя секретное приложение, которое я думаю. Извините, я не могу говорить с большой ясностью по этому поводу, потому что я в основном придерживался PHP SDK, который хорошо документирован. –

+1

Спасибо за подсказку. Посмотрев исходный код и на PHP, они делают это именно так, как предлагает @Roni. Кажется, мне нужно вытащить идентификатор пользователя из подписанного запроса, а не из токена доступа. Спасибо за помощь. – njr101

1

Это очень просто на самом деле.

Когда пользователь загружает ваше приложение, используйте server side authentication, получите токен доступа и загрузите данные пользователя, отправив запрос api с сервера.
На стороне сервера у вас будет все, что вам нужно, и оно изолировано.

Когда страница отображается для пользователя, с использованием js sdk получите данные аутентификации пользователя, вы сможете использовать FB.getLoginStatus, поскольку пользователь уже прошел аутентификацию на стороне сервера.
Теперь на стороне клиента вы также имеете токен доступа, который вы можете использовать для получения пользовательских данных из графика api.

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

Итак, третий вариант, который вы упомянули, для меня звучит лучше всего, и это очень просто реализовать это тоже.


Редактировать

Все Facebook SDKs просто обертками для запроса HTTP, поскольку вся фб апи производится по запросам HTTP.
SDKs просто дают вам легкий и короткий доступ к данным без необходимости создавать URL-адрес самостоятельно (со всеми различными возможными параметрами), делать запрос и анализировать ответ.

Чтобы быть полностью честным, я думаю, что прекращение предоставления возможности SDK для поддержки аутентификации на стороне сервера является очень плохим решением.
В чем смысл предоставления SDK, который не реализует весь api?

Лучший ответ на ваш вопрос, исходя из моего опыта, заключается в использовании аутентификации на сервере и на стороне клиента, а поскольку C# SDK не поддерживает его, я советую вам создать собственный SDK.
Это совсем не сложно, я уже реализовал его для python и java (дважды), и поскольку вы будете разрабатывать его для своих нужд, он может быть адаптирован для ваших конкретных потребностей, в отличие от общедоступного SDK, который должен поддерживать все возможные опции.


второй Редактировать

Там нет необходимости создавать совершенно новый SDK, вы можете просто «расширить» те, которые вы используете, и добавить недостающие части, которые вам нужны, такие как поддержка со стороны аутентификации сервер.

+0

Спасибо за ответ. Документы для состояния C# sdk (http://blog.prabir.me/post/Facebook-CSharp-SDK-Glimpse-into-the-Future.aspx) "... Начиная с версии v6 вам придется использовать Facebook Javascript SDK, чтобы получить токен доступа и передать его на сервер с помощью безопасного соединения https ... ». Поэтому они, похоже, советуют не получать маркер доступа на сервере. Твои мысли? – njr101

+0

Отредактировал свой ответ. –

+0

Я вижу вашу точку зрения, но я действительно хочу избежать обвинений и сохранения моего собственного SDK - в этом весь смысл иметь SDK. Facebook постоянно меняет свои API, и я хочу, чтобы вы могли сосредоточиться на моем домене приложений, а не исправлять нарушения в Facebook каждые две недели. – njr101

Смежные вопросы