/*** * ==++== * * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * ==--== * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ * * Facebook.cpp - Implementation file for simple facebook client. * Note: this implementation will not work until you replace the placeholder * strings below with tokens obtained from facebook. * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ****/ #include "pch.h" #include "facebook.h" using namespace pplx; using namespace web; using namespace Platform; using namespace Windows::Foundation; using namespace Windows::Security::Authentication::Web; using namespace Windows::Storage; // Placeholder strings for app tokens // see blog post at http://aka.ms/FacebookCppRest // for information on obtaining these values const std::wstring application_id(L"insert your application ID"); const std::wstring application_token(L"insert your application token"); facebook_client& facebook_client::instance() { static facebook_client c; return c; } pplx::task facebook_client::login(std::wstring scopes) { // Look in the Local Settings for previously-stored login credentials auto ls = ApplicationData::Current->LocalSettings->CreateContainer("LoginDetailsCache", ApplicationDataCreateDisposition::Always); if(ls->Values->HasKey("facebookToken")) { token_ = dynamic_cast(ls->Values->Lookup("facebookToken"))->Data(); } if(!token_.empty()) { // Check if the token is still valid using namespace http; uri_builder tokendbg_uri(L"/debug_token"); tokendbg_uri.append_query(L"input_token", token_); tokendbg_uri.append_query(L"access_token", application_token); http_request request(methods::GET); request.set_request_uri(tokendbg_uri.to_string()); request.headers().add(header_names::accept, L"application/json"); return raw_client.request(request) .then([](http_response response){ return response.extract_json(); }).then([=](json::value v) -> task { auto obj = v[L"data"]; if(obj[L"is_valid"].as_bool()) { // Currently cached access token is valid signed_in = true; return create_task([](){}); // Return an empty task to match the function's return value } // If the token was invalid, go through full login return full_login(scopes); }, task_continuation_context::use_current()); } // If no token was found, go through full login return full_login(scopes); } pplx::task facebook_client::full_login(std::wstring scopes) { // Create uri for OAuth login on Facebook http::uri_builder login_uri(L"https://www.facebook.com/dialog/oauth"); login_uri.append_query(L"client_id", application_id); // App id login_uri.append_query(L"redirect_uri", L"https://www.facebook.com/connect/login_success.html"); login_uri.append_query(L"scope", scopes); login_uri.append_query(L"display", L"popup"); login_uri.append_query(L"response_type", L"token"); return create_task(WebAuthenticationBroker::AuthenticateAsync( WebAuthenticationOptions::None, ref new Uri(ref new String(login_uri.to_string().c_str())), ref new Uri("https://www.facebook.com/connect/login_success.html"))) .then([=](WebAuthenticationResult^ result) { if(result->ResponseStatus == WebAuthenticationStatus::Success) { signed_in = true; std::wstring response(result->ResponseData->Data()); // Save authentication token auto start = response.find(L"access_token="); start += 13; auto end = response.find('&'); token_ = response.substr(start, end-start); // Add token to Local Settings for future login attempts auto ls = ApplicationData::Current->LocalSettings->CreateContainer("LoginDetailsCache", ApplicationDataCreateDisposition::Always); ls->Values->Insert("facebookToken", ref new String(token_.c_str())); } }); } task facebook_client::get(std::wstring path) { using namespace http; http_request request(methods::GET); request.set_request_uri(base_uri().append_path(path).to_uri()); request.headers().add(header_names::accept, L"application/json"); return raw_client.request(request) .then([](http_response response) { return response.extract_json(); }); } http::uri_builder facebook_client::base_uri(bool absolute) { http::uri_builder ret; if(absolute) ret.set_path(L"https://graph.facebook.com"); ret.append_query(L"access_token", token_); return ret; }