facebook登录没有sdk

时间:2015-04-13 19:08:56

标签: facebook facebook-graph-api oauth

我想在oauth2流程后使用Facebook验证用户身份。

我想在不使用SDK的情况下执行此操作。但我无法理解用户oauth身份验证的端点是什么。

我在哪里可以找到它们?

编辑。这是在移动应用程序中。 IOS或android。

3 个答案:

答案 0 :(得分:2)

答案 1 :(得分:0)

这是我的Android(java)登录名。

    APP_ID = "XXXXXXXXXXXXXXXX"
    RAW_REDIRECT_URI = "https://www.facebook.com/connect/login_success.html";

    // UTF8 adress so it can go along the http request
    REDIRECT_URI ="";
    try {
         REDIRECT_URI = URLEncoder.encode(RAW_REDIRECT_URI, "UTF-8");
    } catch (UnsupportedEncodingException e) {
         e.printStackTrace();
    }

    // get the code or token
    TOKEN_REQUEST = "https://www.facebook.com/v3.2/dialog/oauth?client_id="+APP_ID+"&redirect_uri="+REDIRECT_URI+ "&state=\'{st=state123abc,ds=123456789}\'";


    // start WebView
    webView.setWebViewClient(new WebViewClient() {
        // shouldOverride will run each time a new URL is loaded in the webview.
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            // the loaded URL is our redirect URL
            if(url.startsWith(RAW_REDIRECT_URI)) {
                // here you have two choices...
                // - make a call to your private server to get the token from the code (recommended)
                // - make the API requests because you added a response_type=token in the TOKEN_REQUEST (less secure ) 
            }
            return false;
        }
    });


    // javascript doesn't seem to be needed for facebook but for instagram yes.
    webView.getSettings().setJavaScriptEnabled(true);
    webView.loadUrl(TOKEN_REQUEST);

答案 2 :(得分:0)

我知道,这个帖子已经有点老了,但是我在吐槽,试图实现一个OAuth登录流程,因为Facebook在重定向URL中添加了一个hashtag,它没有到达服务器。 所以我把我的解决方法分享给大家,希望不要让你们也有同样的愤怒。

我使用了一个通用的解决方案,它也可以重复用于其他应用程序。唯一要做的就是在服务器端脚本中添加应用 ID 和应用机密(如下)。

首先,您需要从您的应用调用登录页面:

"https://www.facebook.com/v11.0/dialog/oauth"
    // The app ID can be found in the dashboard (https://developers.facebook.com/apps)
    + "?client_id=" + yourAppId
    // The redirect url in my case (because it's generic)
    // looks like this: https://example.com/oauthresponse/{app}/facebook
    // don't forget to register it in your app dashboard of Facebook:
    // https://developers.facebook.com/apps
    + "&redirect_uri=" + Uri.encode(yourRedirectUrl)
    + "&response_type=token"
    + "&state=" + antiForgeryCode
    + "&scope=" + yourScopes

然后我将其添加到 .htaccess 中:

RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^oauthresponse/(.*)/(.*)(/.*)?$ /oauthresponse.php?app=$1&provider=$2 [L,QSA,NE]

然后这是 oauthresponse.php 脚本:

<?php
// This whole magic is just because facebook is adding a hashtag to the redirect url before the querystring
// the problem is that adding a hashtag with no value makes the querystring beeing interpreted as anchor
// anchors are not sent to servers, only to clients, so what we do is the following:
// We send a javascript, removing the hashtag from the url and redirecting to the new url, 
// so we get the query parameters, which contains the token. Then we use the token to get a long living token.
// After all, we send a redirect header with an app intent url (see createAndroidRedirectUrl()).

// Creates a redirect url that opens an app, according to https://developer.chrome.com/docs/multidevice/android/intents/
function createAndroidRedirectUrl($providr, $application, $query = array())
{
    // You need a scheme, in order for the intent to work, I tested it without and it didn't work...
    $url = "intent://oauthresponse/" . $providr . "#Intent" 
    . ";scheme=ch.aorlinn." . $application 
    . ";package=ch.aorlinn." . $application;
    if(isset($query) && $query != null && count($query))
    {
        foreach($query as $key => $value)
        {
            $url = $url . ";S." . $key . "=" . $value;
        }
    }
    $url = $url . ";end";
    return $url;
}

// Initialize a wait message for the javascript response
$body = "<!DOCTYPE html><html><body><span>Please wait, your beeing redirected...</span><br>";
$requestUri = parse_url($_SERVER['REQUEST_URI']);
$subdomain = explode("/", $requestUri["path"])[2];
$provider = explode("/", $requestUri["path"])[3];
// If this is not a Facebook redirect, add the querystring as extras to the intent, 
// it might contain the token
parse_str($_SERVER['QUERY_STRING'], $redirectExtras);
// Indicates, whether or not to redirect, instead of answering with a body
$isRedirect = true;

// Handle Facebook redirect
if($provider == "facebook")
{
    // Specify the appId and appSecret for this app.
    // You can find it in the app dashboard: https://developers.facebook.com/apps
    if($subdomain == "yourAppName")
    {
        $app_id = "yourAppID";
        $app_secret = "yourSecret";
    }   
    if(isset($app_id) && isset($app_secret))
    {
        $token = $_GET["access_token"];
        if(!isset($token) || strlen($token) <= 0)
        {
            // This parameter is set, when the javascript in the else block did it's magic.
            // It can get here, if the url was called without access_token parameter in the first place.
            // This should only happen, if the page is called from somewhere else than the facebook login page.
            if(isset($_GET["hash_replaced"]) || strlen($_GET["hash_replaced"]) > 0)
            {
                $redirectExtras = array("error" => "hash_replacement");
            }
            else
            {
                // Send a script that sends the user back to the page, but remove the hashtag, 
                // so the whole url is sent to the server and the key might be extracted.
                $isRedirect = false;
                $script = "<script>
                    var loc = window.location.href.replace('#', '');
                    // As the .htaccess already added some parameters, there might be two ? now,
                    // so we split everything by ? and & and build the querystring again.
                    var parts = loc.split(new RegExp('[?&]'));
                    var queryString = '';
                    for(var i = 1; i < parts.length; i++)
                    {
                        queryString = queryString + '&' + parts[i];
                    }
                    window.location.href = parts[0] + '?hash_replaced=true' + queryString;
                    </script>";
                $body = $body . $script;
            }
        }
        else
        {
            // Now request a long living token from Facebook REST API for the application
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, array(
                    "fb_exchange_token" => $token,
                    "client_id" => $app_id,
                    "client_secret" => $app_secret,
                    "grant_type" => "fb_exchange_token"));
            curl_setopt($curl, CURLOPT_URL, "https://graph.facebook.com/v11.0/oauth/access_token");
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            $result = curl_exec($curl);
            curl_close($curl);
            $json = json_decode($result, true);
            $first_key = array_key_first($json);
            if($first_key == "error")
            {
                $array = $json[$first_key];
                $array["error"] = "long_living_token";
                $json = $array;
            }
            $redirectExtras = $json;
        }
    }
}

// This is only false, when the javascript needs to be sent,
// otherwise send a redirect header response (302) with the app intent.
// Note that it needs to be a redirect header. You cannot use javascript here
// as some browsers (like chrome) do not allow to redirect with javascript
// when no user interaction happened.
if($isRedirect)
{
    $redirectUrl = createAndroidRedirectUrl($provider, $subdomain, $redirectExtras);
    
    header("HTTP/1.1 302 Found");
    header("Location: " . $redirectUrl);        
}
else
{
    $body = $body . "</body></html>";
    echo $body;
}
?>

上述功能适用于 Android,但如果您还需要使用 iPhone,只需在响应 url 中添加一个子路径以指示设备类型并在创建重定向 url 之前检查它。