Технологии

Как использовать erl_openid в проектах ChicagoBoss 

У нас сейчас есть проект, который работает на ChicagoBoss (это веб-фреймворк на Эрланге). Мы посмотрели несколько библиотек для работы с OpenID и остановились на erl_openid. Так как это единственная библиотека, которая работает с OpenId 2.0. Так как информации о том как использовать erl_openid в сети нет, то мы сами разобрались с этой библиотекой и решили написать статью о том как запустить эту библиотеку.

v.0.1 Пришлось доработать библиотеу

Библиотека на данный момент не может работать с Google OpenID в связи с тем, что Google отказался от поддержки данной технологии. А для работы с Yandex OpenID пришлось допилить саму библиотеку, так как она не совсем правильно отрабатывала по спецификации в части пункта 7.3.1.

Последний абзац этого пункт содержит информацию: If the end user entered an OP Identifier, there is no Claimed Identifier. For the purposes of making OpenID Authentication requests, the value «http://specs.openid.net/auth/2.0/identifier_select» MUST be used as both the Claimed Identifier and the OP-Local Identifier when an OP Identifier is entered.»

В нашем случае мы указываем только OP Identifier при регистрации в Yandex, то вместо Climed ID должны указать «http://specs.openid.net/auth/2.0/identifier_select», а в erl_openid указывался OP Identifer в любом случае.

v.0.2 Запускаем openid_srv и загружаем нужные библиотеки

Мы не нашли красивого способа как автоматически загрузить нужные библиотеки при старте ChicagoBoss сервера. Поэтому сделали следующим образом — создали файл priv/init/project_02_openid.erl следующего содержания:

-module(project_02_openid).

 

-export([init/0, stop/1]).

init() ->
[application:start(X) || X <- [ crypto, asn1, public_key, ssl, sasl, inets, ibrowse, openid,openid_srv ] ], openid_srv:start_link(openid_srv), {ok, []}. stop(ListOfWatchIDs) ->
[application:stop(X)|| X <-[ crypto, asn1, public_key, ssl, sasl, inets, ibrowse,openid ]].

v.0.3 Запрашиваем OpenID у Yandex

Код следующий:

-module(project_openid_controller, [Req, SessionID]).

-compile(export_all).

-include("openid.hrl").

 

-define(YANDEX_RETURN_URL, "http://test_project/openid/verify_yandex_openid").
-define(MAIN_URL, "http://test_project/").
-define(YANDEX_OPENID_URL, "http://www.yandex.ru/").

yandex_login('GET', []) ->
AuthReq = gen_server:call(openid_srv, {prepare, SessionID, ?YANDEX_OPENID_URL, true}),
yandex_login_result(AuthReq).

yandex_login_result({ok, AuthReq})->
{redirect, openid:authentication_url(AuthReq, ?YANDEX_RETURN_URL, ?MAIN_URL)};
yandex_login_result({error, Error}) ->
{output, Error}.

Здесь все просто, erl_openid предполагает, что сначала вы сделаете "prepare" запрос к openid_srv. А уже openid_srv сделает предусмотренные спецификацией "Associations" и "Discovery". При этом в запросе указывается три параметра:

  • SessionID (обычня строка),
  • Discovery_url (тоже строка)
  • Cache (true, false значения о том включать ли кэш)

Все запрос сделан, полученный результат обрабатывается и если все хорошо делается редирект на openid:authentication_url

v.0.4 Верификация

К контроллеру project_openid_controller добавляем:

verify_yandex_openid('GET', []) ->
VerifyResult = gen_server:call(openid_srv, {verify, SessionID, ?YANDEX_RETURN_URL, Req:query_params()}),
verify_yandex_openid_result(VerifyResult).

 

verify_yandex_openid_result({ok, OpenID})->
auth_lib:set_session_login(SessionID, OpenID),
case auth_lib:check_user_profile(OpenID) of
undefined ->
{redirect, "/profile/signup"};
WebUser ->
{redirect, "/"}
end;

verify_yandex_openid_result({error, Error}) ->
{output, Error}.

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

v.1.0 (alfa) Заключение

Мы не стали подробно рассматривать как регистрировать у себя в проекте пользователя после идентификации через OpenID, но я думаю, вы тут и сами разберитесь. А на этом все!

RU/KZ