Лучший способ реализовать единый вход со всеми основными поставщиками?


Я уже провел много исследований на эту тему и сам внедрил множество решений.

OpenID Facebook Connect (с использованием старого API Rest и нового API Graph OAuth 2.0), войдите в систему с помощью twitter (который, насколько я знаю, к настоящему времени обновлен до полностью квалифицированного OpenID) и так далее.

Включая OpenID, Facebook Connect (с использованием старого API Rest и нового API Graph OAuth 2.0), войдите в Twitter (который, насколько я знаю, был обновлен до полностью квалифицированного OpenID) и так далее...

Но чего мне все еще не хватает, так это идеального решения "все в одном".

Во время своего исследования я наткнулся на некоторые интересные проекты:

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

Я также видел разработчиков, реализующих одну услугу после другой послушно следует инструкциям поставщиков и настраивает модели и таблицы базы данных для всего.

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

То, что я ищу, - это уровень абстракции , который сводит все сервисы к одному стандарту, который может быть интегрирован в мой веб-сайт. Как только появится новая услуга, я хочу добавить только одну модель, которая занимается абстракцией этот конкретный поставщик, чтобы я мог легко интегрировать его в свое приложение.

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

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

Последнее из 3 приведенных выше решений выглядит многообещающим с точки зрения концепции. Все просто перенесено на синтетический OpenID, и веб-сайт просто должен реализовать Идентификатор OpenID.

Через некоторое время я нашел Django socialauth, систему аутентификации на основе python для веб-фреймворка Django. Но похоже, что он работает так, как описано выше, и я думаю, что это та же система входа в систему, которую использует Stackoverflow (или, по крайней мере, какая-то модифицированная вилка...).

Я скачал его и попытался настроить и посмотреть, можно ли его настроить как отдельное решение, но мне не повезло, так как я тоже не очень разбираюсь в python.

Я бы хотел использовать PHP на основе решение.

Итак, после этого длинного текста мой вопрос точно таков:

  • Как бы вы реализовали единый вход, есть ли идея получше, чем переносить все и использовать OpenID в качестве основы?
  • Каковы плюсы и минусы этого?
  • Знаете ли вы какие-либо уже существующие решения? Предпочтительно с открытым исходным кодом.

Я надеюсь, что этот вопрос не слишком субъективен, заранее спасибо.

Обновление: Я пришел к выводу, что создание прокси-сервера/оболочки или как вы могли бы это назвать для Facebook, перенести его OpenID, чтобы он стал конечной точкой/поставщиком OpenID, было бы лучшим вариантом. Так что именно это я и сделал.

Пожалуйста, смотрите мой ответ ниже.

Я добавил награду, чтобы получить отзывы/обсуждения по этому поводу. Мэби, мой подход не так хорош, как я сейчас думаю!

Author: sobbe, 2010-10-31

3 answers

Как первоначальный автор этого ответа, я хочу отметить, что я рассматриваю его как УСТАРЕВШИЙ . Поскольку большинство провайдеров решили реализовать исключительно Oauth вместо Openid. Более новые службы Openid также, скорее всего, будут использовать openid connect, основанный на oauth. Есть хорошие библиотеки, такие как, например: https://github.com/hybridauth/hybridauth

После обсуждения уже существующего ответа я подвожу итог:

Почти каждый крупный поставщик является поставщик/конечная точка openid, включая Google, Yahoo, Aol.

Некоторые из них требуют от пользователя указать имя пользователя для создания конечной точки openid. У некоторых из них (упомянутых выше) есть URL-адреса обнаружения, где идентификатор пользователя автоматически возвращается, так что пользователю нужно только щелкнуть. (я был бы рад, если бы кто-нибудь мог объяснить техническую подоплеку)

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

{[5 facebook]} Теперь я сделал для своего проекта настройку поставщика openid, который аутентифицирует пользователя с помощью учетных данных моего приложения facebook, чтобы пользователь подключался к моему приложению, и возвращает идентификатор пользователя, который выглядит так:
http://my-facebook-openid-proxy-subdomain.mydomain.com/?id=facebook-user-id

Я также настроил его для получения адреса электронной почты и имени и возврата их в качестве атрибутов AX.

Так что мой сайт просто должен реализовать идентификатор открытия, и я в порядке:)

Я строю его на классах, которые вы можете найти здесь: http://gitorious.org/lightopenid

В моем index.php файл я просто называю его так:

<?php
require 'LightOpenIDProvider.php';
require 'FacebookProvider.php';
$op = new FacebookProvider;
$op->appid = 148906418456860; // your facebook app id
$op->secret = 'mysecret'; // your facebook app secret
$op->baseurl = 'http://fbopenid.2xfun.com'; // needs to be allowed by facebook
$op->server();
?>

И исходный код FacebookProvider.php следует:

<?php
class FacebookProvider extends LightOpenIDProvider
{
    public $appid = "";
    public $appsecret = "";
    public $baseurl = "";

    // i have really no idea what this is for. just copied it from the example.
    public $select_id = true;

    function __construct() {

        $this->baseurl = rtrim($this->baseurl,'/'); // no trailing slash as it will be concatenated with
                                                    // request uri wich has leading slash

        parent::__construct();

        # If we use select_id, we must disable it for identity pages,
        # so that an RP can discover it and get proper data (i.e. without select_id)
        if(isset($_GET['id'])) {
            // i have really no idea what happens here. works with or without! just copied it from the example.
            $this->select_id = false;
        }
    }

    function setup($identity, $realm, $assoc_handle, $attributes)
    {
        // here we should check the requested attributes and adjust the scope param accordingly
        // for now i just hardcoded email
        $attributes = base64_encode(serialize($attributes));    

        $url = "https://graph.facebook.com/oauth/authorize?client_id=".$this->appid."&redirect_uri=";

        $redirecturl = urlencode($this->baseurl.$_SERVER['REQUEST_URI'].'&attributes='.$attributes);
        $url .= $redirecturl;
        $url .= "&display=popup";
        $url .= "&scope=email";
        header("Location: $url");
        exit();        

    }

    function checkid($realm, &$attributes)
    {
        // try authenticating
        $code = isset($_GET["code"]) ? $_GET["code"] : false;
        if(!$code) {
            // user has not authenticated yet, lets return false so setup redirects him to facebook
            return false;
        }

        // we have the code parameter set so it looks like the user authenticated
        $url = "https://graph.facebook.com/oauth/access_token?client_id=148906418456860&redirect_uri=";

        $redirecturl = ($this->baseurl.$_SERVER['REQUEST_URI']);
        $redirecturl = strstr($redirecturl, '&code', true);
        $redirecturl = urlencode($redirecturl);     
        $url .= $redirecturl;
        $url .= "&client_secret=".$this->secret;
        $url .= "&code=".$code;
        $data = $this->get_data($url);

        parse_str($data,$data);

        $token = $data['access_token'];

        $data = $this->get_data('https://graph.facebook.com/me?access_token='.urlencode($token));
        $data = json_decode($data);

        $id = $data->id;
        $email = $data->email;
        $attribute_map = array(
            'namePerson/friendly' => 'name', // we should parse the facebook link to get the nickname
            'contact/email' => 'email',
        );

        if($id > 0) {

            $requested_attributes = unserialize(base64_decode($_GET["attributes"]));

            // lets be nice and return everything we can
            $requested_attributes = array_merge($requested_attributes['required'],$requested_attributes['optional']);
            $attributes = array();
            foreach($requested_attributes as $requsted_attribute) {
                if(!isset($data->{$attribute_map[$requsted_attribute]})) {
                    continue; // unknown attribute
                }
                $attributes[$requsted_attribute] = $data->{$attribute_map[$requsted_attribute]};    
            }

            // yeah authenticated!
            return $this->serverLocation . '?id=' . $id ;
        }
        die('login failed'); // die so we dont retry bouncing back to facebook
        return false;
    }
    function get_data($url) { 
      $ch = curl_init();
      $timeout = 5;
      curl_setopt($ch,CURLOPT_URL,$url);
      curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
      curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout);
      $data = curl_exec($ch);
      curl_close($ch);
      return $data;
    }    

}

Это всего лишь первая рабочая версия (быстрая и грязная) Некоторые динамические вещи жестко запрограммированы в соответствии с моими потребностями. Это должно показать, как и что это можно сделать. Я рад, если кто-то возьмет и улучшит его, или перепишет, или что-то еще:)

Что ж, я считаю, что на этот вопрос дан ответ

Но я добавьте награду просто для того, чтобы получить обсуждение. Я хотел бы знать, что вы думаете о моем решении.

Я назначу награду за лучший ответ/комментарий рядом с этим.

 13
Author: The Surrican, 2017-10-14 12:12:17

OpenID будет вашим лучшим выбором для этого приложения. Он поддерживается многими поставщиками:

  • Google
  • Yahoo
  • Миопенид
  • AOL

Единственная проблема заключается в том, что twitter еще не реализовал OpenID. Вероятно, это связано с тем, что они являются частной компанией, поэтому они хотели иметь свое "собственное" решение.

Чтобы решить это решение, вы можете написать класс-оболочку для обеспечения совместимости с OpenID, но есть вероятность, что даже если у ваших пользователей нет учетной записи Twitter, у них может быть учетная запись Facebook, Google или Yahoo.

Facebook поддерживает oauth, поэтому вам придется перенести oauth на OpenID

Некоторые библиотеки PHP для OpenID можно найти здесь.

Теперь были подняты некоторые вопросы о том, что facebook является поставщиком oauth.

Их URL-адрес oauth"https://graph.facebook.com/oauth/authorize "

Если вы все еще не верите мне, то можете посмотреть на этот файл javascript, где я получил этот URL. Если вы не верите этому файлу javascript, обратите внимание, что он размещен на stackexchange, поставщике этого сайта. Теперь вы должны поверить в это.

 5
Author: xaav, 2010-11-02 21:19:09

Перенесемся на два года вперед, и ответ "OpenID - это ответ", похоже, уходит на второй план рядом крупных провайдеров. Большинство крупных сторонних сайтов интеграции, похоже, перешли на какой-то вариант OAuth (обычно OAuth2). Кроме того, если вы не возражаете НЕ использовать OpenID/OAuth, теперь есть полное решение единого входа, написанное на PHP (отказ от ответственности и полное раскрытие: Этот продукт разработан и поддерживается мной под баннером CubicleSoft):

Одиночный Сервер/Клиент для входа в систему

Которого не существовало, когда этот вопрос был задан изначально. Он имеет либеральную лицензию (MIT или LGPL) и отвечает вашим требованиям быть уровнем абстракции. Проект, как правило, ориентирован на корпоративные входы, но в нем также есть некоторые входы в социальные сети (Google и Facebook).

Возможно, вы также захотите взглянуть на HybridAuth, который ориентирован только на вход в социальные сети, но является скорее библиотекой, чем готовым решением, которое вы можете бросить на сервер и покончить с этим. Так что с его настройкой предстоит еще немного поработать. Это действительно зависит от того, что вам нужно.

Если вы довольны своим решением OpenID, то отлично, но сегодня вариантов больше, чем было два года назад, и люди все еще находят эту тему.

 2
Author: CubicleSoft, 2015-06-21 14:32:48